LDAPLostPasswordHandler   A
last analyzed

Complexity

Total Complexity 19

Size/Duplication

Total Lines 210
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 94
c 1
b 0
f 0
dl 0
loc 210
rs 10
wmc 19

9 Methods

Rating   Name   Duplication   Size   Complexity  
A setService() 0 4 1
A getService() 0 3 1
A lostPasswordForm() 0 18 2
A __construct() 0 5 1
A passwordsent() 0 20 2
A getMemberFromData() 0 15 3
A lostpassword() 0 18 2
B validateForgotPasswordData() 0 44 6
A redirectToSuccess() 0 9 1
1
<?php
2
3
namespace SilverStripe\LDAP\Authenticators;
4
5
use SilverStripe\Control\Controller;
6
use SilverStripe\Control\Email\Email;
7
use SilverStripe\Control\HTTPResponse;
8
use SilverStripe\Core\Config\Config;
9
use SilverStripe\Core\Convert;
10
use SilverStripe\Core\Injector\Injector;
11
use SilverStripe\Forms\FieldList;
12
use SilverStripe\Forms\Form;
13
use SilverStripe\Forms\FormAction;
14
use SilverStripe\Forms\TextField;
15
use SilverStripe\LDAP\Services\LDAPService;
16
use SilverStripe\ORM\FieldType\DBField;
17
use SilverStripe\Security\Member;
18
use SilverStripe\Security\MemberAuthenticator\LostPasswordForm;
19
use SilverStripe\Security\MemberAuthenticator\LostPasswordHandler;
20
use SilverStripe\Security\Security;
21
22
class LDAPLostPasswordHandler extends LostPasswordHandler
23
{
24
    protected $authenticatorClass = LDAPAuthenticator::class;
25
26
    /**
27
     * Since the logout and dologin actions may be conditionally removed, it's necessary to ensure these
28
     * remain valid actions regardless of the member login state.
29
     *
30
     * @var array
31
     * @config
32
     */
33
    private static $allowed_actions = [
0 ignored issues
show
introduced by
The private property $allowed_actions is not used, and could be removed.
Loading history...
34
        'lostpassword',
35
        'LostPasswordForm',
36
        'passwordsent',
37
    ];
38
39
    private static $dependencies = [
0 ignored issues
show
introduced by
The private property $dependencies is not used, and could be removed.
Loading history...
40
        'service' => '%$' . LDAPService::class,
41
    ];
42
43
    /**
44
     * @var LDAPService
45
     */
46
    protected $service;
47
48
    /**
49
     * LDAP data for the provided member - is loaded by validateForgotPasswordData
50
     *
51
     * @var array
52
     */
53
    protected $ldapUserData = [];
54
55
56
    /**
57
     * @param string $link The URL to recreate this request handler
58
     * @param LDAPAuthenticator $authenticator
59
     */
60
    public function __construct($link, LDAPAuthenticator $authenticator)
61
    {
62
        $this->link = $link;
63
        $this->authenticatorClass = get_class($authenticator);
64
        parent::__construct($link);
65
    }
66
67
    protected function validateForgotPasswordData(array $data, LostPasswordForm $form)
68
    {
69
        Config::modify()->set(Member::class, 'unique_identifier_field', 'Login');
70
71
        // No need to protect against injections, LDAPService will ensure that this is safe
72
        $login = isset($data['Login']) ? trim($data['Login']) : '';
73
74
        // Ensure something was provided
75
        if (empty($login)) {
76
            if (Config::inst()->get(LDAPAuthenticator::class, 'allow_email_login') === 'yes') {
77
                $form->sessionMessage(
78
                    _t(
79
                        'SilverStripe\\LDAP\\Forms\\LDAPLoginForm.ENTERUSERNAMEOREMAIL',
80
                        'Please enter your username or your email address to get a password reset link.'
81
                    ),
82
                    'bad'
83
                );
84
            } else {
85
                $form->sessionMessage(
86
                    _t(
87
                        'SilverStripe\\LDAP\\Forms\\LDAPLoginForm.ENTERUSERNAME',
88
                        'Please enter your username to get a password reset link.'
89
                    ),
90
                    'bad'
91
                );
92
            }
93
            return $this->redirectBack();
94
        }
95
96
        // Look up the user and store it
97
        if (Email::is_valid_address($login)) {
98
            if (Config::inst()->get(LDAPAuthenticator::class, 'allow_email_login') != 'yes') {
99
                $form->sessionMessage(
100
                    _t(
101
                        'SilverStripe\\LDAP\\Forms\\LDAPLoginForm.USERNAMEINSTEADOFEMAIL',
102
                        'Please enter your username instead of your email to get a password reset link.'
103
                    ),
104
                    'bad'
105
                );
106
                return $this->redirect($this->Link('lostpassword'));
107
            }
108
            $this->ldapUserData = $this->getService()->getUserByEmail($login);
109
        } else {
110
            $this->ldapUserData = $this->getService()->getUserByUsername($login);
111
        }
112
    }
113
114
    protected function getMemberFromData(array $data)
115
    {
116
        $member = Member::get()->filter('GUID', $this->ldapUserData['objectguid'])->limit(1)->first();
117
118
        // User haven't been imported yet so do that now
119
        if (!$member || !$member->exists()) {
0 ignored issues
show
introduced by
$member is of type SilverStripe\ORM\DataObject, thus it always evaluated to true.
Loading history...
120
            $member = Member::create();
121
            $member->GUID = $this->ldapUserData['objectguid'];
122
        }
123
124
        // Update the users from LDAP so we are sure that the email is correct.
125
        // This will also write the Member record.
126
        $this->getService()->updateMemberFromLDAP($member, $this->ldapUserData, false);
127
128
        return $member;
129
    }
130
131
    protected function redirectToSuccess(array $data)
132
    {
133
        $link = Controller::join_links(
134
            $this->link('passwordsent'),
135
            rawurlencode($data['Login']),
136
            '/'
137
        );
138
139
        return $this->redirect($this->addBackURLParam($link));
140
    }
141
142
    /**
143
     * Factory method for the lost password form
144
     *
145
     * @return Form Returns the lost password form
146
     */
147
    public function lostPasswordForm()
148
    {
149
        $loginFieldLabel = (Config::inst()->get(LDAPAuthenticator::class, 'allow_email_login') === 'yes') ?
150
            _t('SilverStripe\\LDAP\\Forms\\LDAPLoginForm.USERNAMEOREMAIL', 'Username or email') :
151
            _t('SilverStripe\\LDAP\\Forms\\LDAPLoginForm.USERNAME', 'Username');
152
        $loginField = TextField::create('Login', $loginFieldLabel);
153
154
        $action = FormAction::create(
155
            'forgotPassword',
156
            _t('SilverStripe\\Security\\Security.BUTTONSEND', 'Send me the password reset link')
157
        );
158
        return LostPasswordForm::create(
159
            $this,
160
            $this->authenticatorClass,
161
            'LostPasswordForm',
162
            FieldList::create([$loginField]),
163
            FieldList::create([$action]),
164
            false
165
        );
166
    }
167
168
    public function lostpassword()
169
    {
170
        if (Config::inst()->get(LDAPAuthenticator::class, 'allow_email_login') === 'yes') {
171
            $message = _t(
172
                __CLASS__ . '.NOTERESETPASSWORDUSERNAMEOREMAIL',
173
                'Enter your username or your email address and we will send you a link with which '
174
                . 'you can reset your password'
175
            );
176
        } else {
177
            $message = _t(
178
                __CLASS__ . '.NOTERESETPASSWORDUSERNAME',
179
                'Enter your username and we will send you a link with which you can reset your password'
180
            );
181
        }
182
183
        return [
184
            'Content' => DBField::create_field('HTMLFragment', "<p>$message</p>"),
185
            'Form' => $this->lostPasswordForm(),
186
        ];
187
    }
188
189
    public function passwordsent()
190
    {
191
        $username = Convert::raw2xml(
192
            rawurldecode($this->getRequest()->param('OtherID'))
193
        );
194
        $username .= ($extension = $this->getRequest()->getExtension()) ? '.' . $extension : '';
195
196
        return [
197
            'Title' => _t(
198
                __CLASS__ . '.PASSWORDSENTHEADER',
199
                "Password reset link sent to '{username}'",
200
                ['username' => $username]
201
            ),
202
            'Content' =>
203
                _t(
204
                    __CLASS__ . '.PASSWORDSENTTEXT',
205
                    "Thank you! A reset link has been sent to '{username}', provided an account exists.",
206
                    ['username' => $username]
207
                ),
208
            'Username' => $username
209
        ];
210
    }
211
212
    /**
213
     * Get the LDAP service
214
     *
215
     * @return LDAPService
216
     */
217
    public function getService()
218
    {
219
        return $this->service;
220
    }
221
222
    /**
223
     * Set the LDAP service
224
     *
225
     * @param LDAPService $service
226
     * @return $this
227
     */
228
    public function setService(LDAPService $service)
229
    {
230
        $this->service = $service;
231
        return $this;
232
    }
233
}
234