Completed
Push — master ( 77744b...07719b )
by Sean
02:20
created

LDAPChangePasswordForm::doChangePassword()   D

Complexity

Conditions 13
Paths 54

Size

Total Lines 100
Code Lines 60

Duplication

Lines 29
Ratio 29 %

Importance

Changes 5
Bugs 0 Features 1
Metric Value
c 5
b 0
f 1
dl 29
loc 100
rs 4.9922
cc 13
eloc 60
nc 54
nop 1

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
class LDAPChangePasswordForm extends ChangePasswordForm
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
4
{
5
    /**
6
     * The sole purpose for overriding the constructor is surfacing the username to the user.
7
     */
8
    public function __construct($controller, $name, $fields = null, $actions = null)
9
    {
10
        parent::__construct($controller, $name, $fields, $actions);
11
12
        // Obtain the Member object. If the user got this far, they must have already been synced.
13
        $member = Member::currentUser();
14 View Code Duplication
        if (!$member) {
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...
15
            if (Session::get('AutoLoginHash')) {
16
                $member = Member::member_from_autologinhash(Session::get('AutoLoginHash'));
17
            }
18
19
            // The user is not logged in and no valid auto login hash is available
20
            if (!$member) {
21
                Session::clear('AutoLoginHash');
22
                return $this->controller->redirect($this->controller->Link('login'));
0 ignored issues
show
Unused Code introduced by
The call to Controller::Link() has too many arguments starting with 'login'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
Bug introduced by
Constructors do not have meaningful return values, anything that is returned from here is discarded. Are you sure this is correct?
Loading history...
23
            }
24
        }
25
26
        $data = Injector::inst()->get('LDAPService')->getUserByGUID($member->GUID, array('samaccountname'));
27
28
        $emailField = null;
29
        $usernameField = null;
30
        if (Config::inst()->get('LDAPAuthenticator', 'allow_email_login')==='yes' && !empty($member->Email)) {
31
            $emailField = new TextField('Email', _t('LDAPLoginForm.USERNAMEOREMAIL', 'Email'), $member->Email, null, $this);
32
        }
33
        if (!empty($data['samaccountname'])) {
34
            $usernameField = new TextField('Username', _t('LDAPLoginForm.USERNAME', 'Username'), $data['samaccountname'], null, $this);
35
        }
36
37
        if ($emailField) {
38
            $emailFieldReadonly = $emailField->performDisabledTransformation();
39
            $this->Fields()->unshift($emailFieldReadonly);
40
        }
41
        if ($usernameField) {
42
            $usernameFieldReadonly = $usernameField->performDisabledTransformation();
43
            $this->Fields()->unshift($usernameFieldReadonly);
44
        }
45
    }
46
47
    /**
48
     * Change the password
49
     *
50
     * @param array $data The user submitted data
51
     * @return SS_HTTPResponse
52
     */
53
    public function doChangePassword(array $data)
0 ignored issues
show
Coding Style introduced by
doChangePassword uses the super-global variable $_REQUEST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
54
    {
55
        /**
56
         * @var LDAPService $service
57
         */
58
        $service = Injector::inst()->get('LDAPService');
59
        $member = Member::currentUser();
60
        if ($member) {
61
            try {
62
                $userData = $service->getUserByGUID($member->GUID);
63
            } catch (Exception $e) {
64
                SS_Log::log($e->getMessage(), SS_Log::ERR);
65
                $this->clearMessage();
66
                $this->sessionMessage(
67
                    _t('LDAPAuthenticator.NOUSER', 'Your account hasn\'t been setup properly, please contact an administrator.'),
68
                    'bad'
69
                );
70
                return $this->controller->redirect($this->controller->Link('changepassword'));
0 ignored issues
show
Unused Code introduced by
The call to Controller::Link() has too many arguments starting with 'changepassword'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
71
            }
72
            $loginResult = $service->authenticate($userData['samaccountname'], $data['OldPassword']);
73 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...
74
                $this->clearMessage();
75
                $this->sessionMessage(
76
                    _t('Member.ERRORPASSWORDNOTMATCH', "Your current password does not match, please try again"),
77
                    "bad"
78
                );
79
                // redirect back to the form, instead of using redirectBack() which could send the user elsewhere.
80
                return $this->controller->redirect($this->controller->Link('changepassword'));
0 ignored issues
show
Unused Code introduced by
The call to Controller::Link() has too many arguments starting with 'changepassword'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
81
            }
82
        }
83
84 View Code Duplication
        if (!$member) {
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...
85
            if (Session::get('AutoLoginHash')) {
86
                $member = Member::member_from_autologinhash(Session::get('AutoLoginHash'));
87
            }
88
89
            // The user is not logged in and no valid auto login hash is available
90
            if (!$member) {
91
                Session::clear('AutoLoginHash');
92
                return $this->controller->redirect($this->controller->Link('login'));
0 ignored issues
show
Unused Code introduced by
The call to Controller::Link() has too many arguments starting with 'login'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
93
            }
94
        }
95
96
        // Check the new password
97
        if (empty($data['NewPassword1'])) {
98
            $this->clearMessage();
99
            $this->sessionMessage(
100
                _t('Member.EMPTYNEWPASSWORD', "The new password can't be empty, please try again"),
101
                "bad");
102
103
            // redirect back to the form, instead of using redirectBack() which could send the user elsewhere.
104
            return $this->controller->redirect($this->controller->Link('changepassword'));
0 ignored issues
show
Unused Code introduced by
The call to Controller::Link() has too many arguments starting with 'changepassword'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
105
        } elseif ($data['NewPassword1'] == $data['NewPassword2']) {
106
            // Providing OldPassword to perform password _change_ operation. This will respect the
107
            // password history policy. Unfortunately we cannot support password history policy on password _reset_
108
            // at the moment, which means it will not be enforced on SilverStripe-driven email password reset.
109
            $oldPassword = !empty($data['OldPassword']) ? $data['OldPassword']: null;
110
            $isValid = $service->setPassword($member, $data['NewPassword1'], $oldPassword);
0 ignored issues
show
Compatibility introduced by
$member of type object<DataObject> is not a sub-type of object<Member>. It seems like you assume a child class of the class DataObject 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...
111
112
            // try to catch connection and other errors that the ldap service can through
113
            if ($isValid->valid()) {
114
                $member->logIn();
115
116
                Session::clear('AutoLoginHash');
117
118
                // Clear locked out status
119
                $member->LockedOutUntil = null;
120
                $member->FailedLoginCount = null;
121
                $member->write();
122
123
                if (!empty($_REQUEST['BackURL'])
124
                    // absolute redirection URLs may cause spoofing
125
                    && Director::is_site_url($_REQUEST['BackURL'])
126
                ) {
127
                    $url = Director::absoluteURL($_REQUEST['BackURL']);
128
                    return $this->controller->redirect($url);
129
                } else {
130
                    // Redirect to default location - the login form saying "You are logged in as..."
131
                    $redirectURL = HTTP::setGetVar(
132
                        'BackURL',
133
                        Director::absoluteBaseURL(), $this->controller->Link('login')
0 ignored issues
show
Unused Code introduced by
The call to Controller::Link() has too many arguments starting with 'login'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
Security Bug introduced by
It seems like \Director::absoluteBaseURL() targeting Director::absoluteBaseURL() can also be of type false; however, HTTP::setGetVar() does only seem to accept string, did you maybe forget to handle an error condition?
Loading history...
134
                    );
135
                    return $this->controller->redirect($redirectURL);
136
                }
137
            } else {
138
                $this->clearMessage();
139
                $this->sessionMessage($isValid->message(), "bad");
140
                // redirect back to the form, instead of using redirectBack() which could send the user elsewhere.
141
                return $this->controller->redirect($this->controller->Link('changepassword'));
0 ignored issues
show
Unused Code introduced by
The call to Controller::Link() has too many arguments starting with 'changepassword'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
142
            }
143 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...
144
            $this->clearMessage();
145
            $this->sessionMessage(
146
                _t('Member.ERRORNEWPASSWORD', "You have entered your new password differently, try again"),
147
                "bad");
148
149
            // redirect back to the form, instead of using redirectBack() which could send the user elsewhere.
150
            return $this->controller->redirect($this->controller->Link('changepassword'));
0 ignored issues
show
Unused Code introduced by
The call to Controller::Link() has too many arguments starting with 'changepassword'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
151
        }
152
    }
153
}
154