FeManagerHooks.php 11.2 KB
Newer Older
Stefan Busemann's avatar
Stefan Busemann committed
1
<?php
2
namespace T3o\T3omy\Hooks;
Stefan Busemann's avatar
Stefan Busemann committed
3

Stefan Busemann's avatar
Stefan Busemann committed
4
5
6
/***************************************************************
 * Copyright notice
 *
7
 * (c) 2017 Stefan Busemann (in2code GmbH)
Stefan Busemann's avatar
Stefan Busemann committed
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 * All rights reserved
 *
 * This script is part of the TYPO3 project. The TYPO3 project is
 * free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * The GNU General Public License can be found at
 * http://www.gnu.org/copyleft/gpl.html.
 * A copy is found in the textfile GPL.txt and important notices to the license
 * from the author is found in LICENSE.txt distributed with these scripts.
 *
 *
 * This script is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * This copyright notice MUST APPEAR in all copies of the script!
 ***************************************************************/
Stefan Busemann's avatar
Stefan Busemann committed
29

30
31
use In2code\Femanager\Controller\NewController;
use In2code\Femanager\Controller\UserBackendController;
32
use In2code\Femanager\Domain\Model\User;
33
34
use In2code\Femanager\Domain\Service\SendMailService;
use In2code\Femanager\Utility\StringUtility;
Stefan Busemann's avatar
Stefan Busemann committed
35
use T3o\T3oLdap\Utility\UserCreateUpdateDelete;
Stefan Busemann's avatar
Stefan Busemann committed
36
use TYPO3\CMS\Core\TypoScript\TypoScriptService;
37
use TYPO3\CMS\Core\Utility\GeneralUtility;
38
use TYPO3\CMS\Extbase\Object\ObjectManager;
Stefan Busemann's avatar
Stefan Busemann committed
39

Stefan Busemann's avatar
Stefan Busemann committed
40
/**
41
 * Hook Functions
Stefan Busemann's avatar
Stefan Busemann committed
42
 */
43
class FeManagerHooks
44
{
Stefan Busemann's avatar
Stefan Busemann committed
45
    /**
Stefan Busemann's avatar
Stefan Busemann committed
46
     * @var UserCreateUpdateDelete
Stefan Busemann's avatar
Stefan Busemann committed
47
     */
Stefan Busemann's avatar
Stefan Busemann committed
48
    protected $ldapUserCreateUpdateDelete;
Stefan Busemann's avatar
Stefan Busemann committed
49

Stefan Busemann's avatar
Stefan Busemann committed
50
    /**
51
     * @var array
Stefan Busemann's avatar
Stefan Busemann committed
52
53
54
     */
    protected $settings;

55
56
57
58
59
    /**
     * @var array
     */
    protected $fullTS;

60
61
62
63
64
65
    /**
     * @var \T3o\T3omy\Domain\Repository\MyProfileRepository
     * @inject
     */
    protected $myProfileRepository;

66
67
68
69
70
71
    /**
     * @var \TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager
     * @inject
     */
    protected $persistenceManager;

Stefan Busemann's avatar
Stefan Busemann committed
72
73
74
    /**
     * DataHandlerHook constructor
     */
75
76
    public function __construct()
    {
77
78
        $this->getTSConfiguration();
        $this->ldapUserCreateUpdateDelete = new UserCreateUpdateDelete();
Stefan Busemann's avatar
Stefan Busemann committed
79
80
    }

81
82
83
84
85
86
    /**
     * @param \In2code\Femanager\Domain\Model\User $user
     * @param \In2code\Femanager\Controller\NewController $plugin
     * @return void
     */
    public function newUserNotification(User $user, NewController $plugin)
Stefan Busemann's avatar
Stefan Busemann committed
87
88
    {
        // this event happens, when a user registered himself and no autoapprovement got active
89

Stefan Busemann's avatar
Stefan Busemann committed
90
91
        $this->sendConfirmationEmail($user);

Stefan Busemann's avatar
Stefan Busemann committed
92
93
94
95
96
97
98
        $this->sendSlackBotMessage(
            'New User Registration',
            sprintf(
                'new user registered on typo3.org with username: *%s* email: *%s* name: *%s* and IP located in: %s',
                $user->getUsername(),
                $user->getEmail(),
                $user->getName(),
99
                $this->getLocationDataByIp()
Stefan Busemann's avatar
Stefan Busemann committed
100
101
102
103
104
105
            ),
            'notice'
        );

    }

106
107
108
109
110
111
    /**
     * @param \In2code\Femanager\Domain\Model\User $user
     * @param \In2code\Femanager\Controller\NewController $plugin
     * @return void
     */
    public function newUserAutoApprovement(User $user, NewController $plugin)
Stefan Busemann's avatar
Stefan Busemann committed
112
    {
113

Stefan Busemann's avatar
Stefan Busemann committed
114
        // this event happens, when a user registered himself and an autoapprovement got active
Stefan Busemann's avatar
Stefan Busemann committed
115
116
        $this->createUser($user);

Stefan Busemann's avatar
Stefan Busemann committed
117
118
119
120
121
122
123
        $this->sendSlackBotMessage(
            'New user auto approvement',
            sprintf(
                'new user registered on typo3.org with username: *%s* email: *%s* name: *%s* and IP located in: %s was auto approved',
                $user->getUsername(),
                $user->getEmail(),
                $user->getName(),
124
                $this->getLocationDataByIp()
Stefan Busemann's avatar
Stefan Busemann committed
125
126
127
128
129
            ),
            'info'
        );
    }

130
131
    /**
     * @param User $user
132
133
     * @param \In2code\Femanager\Controller\UserBackendController $plugin
     * @return void
134
     */
135
    public function newUserAdminApprovement(User $user, UserBackendController $plugin)
Stefan Busemann's avatar
Stefan Busemann committed
136
    {
137
        $this->createUser($user);
138

139
        #User was approved via backend
Stefan Busemann's avatar
Stefan Busemann committed
140
141
142
143
144
145
146
147
148
149
150
151
        $this->sendSlackBotMessage(
            'User approved',
            sprintf(
                'the user *%s* with email *%s* has been approved by *%s*',
                $user->getUsername(),
                $user->getEmail(),
                $GLOBALS['BE_USER']->user['username']
            ),
            'ok'
        );
    }

152
153
    /**
     * @param User $user
154
155
     * @param \In2code\Femanager\Controller\UserBackendController $plugin
     * @return void
156
     */
157
    public function newUserAdminDecline(User $user, UserBackendController $plugin)
Stefan Busemann's avatar
Stefan Busemann committed
158
    {
159
        #User was approved via backend
Stefan Busemann's avatar
Stefan Busemann committed
160
161
162
163
        $this->sendSlackBotMessage(
            'User declined',
            sprintf(
                'the user *%s* with email *%s* has been declined by *%s*',
Stefan Busemann's avatar
Stefan Busemann committed
164
                $user->getUsername(),
Stefan Busemann's avatar
Stefan Busemann committed
165
166
167
168
169
                $user->getEmail(),
                $GLOBALS['BE_USER']->user['username']
            ),
            'danger'
        );
Stefan Busemann's avatar
Stefan Busemann committed
170
171
    }

172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
    /**
     * @param \In2code\Femanager\Domain\Model\User $user
     * @param \In2code\Femanager\Controller\EditController $plugin
     * @return void
     */
    public function selfUpdateOfUser(User $user, \In2code\Femanager\Controller\EditController $plugin)
    {
        $myProfileUser = $this->myProfileRepository->findDisabledByUid($user->getUid());
        $plainTextPassword = '';
        if ($user->_isDirty('password')) {
            $plainTextPassword = $user->getPassword();
            \In2code\Femanager\Utility\UserUtility::convertPassword($user, '');
            $cryptedPassword = $user->getPassword();
            $myProfileUser->setPassword($cryptedPassword);
        }
        $this->ldapUserCreateUpdateDelete->updateUser($myProfileUser, true, $plainTextPassword);
    }

Stefan Busemann's avatar
Stefan Busemann committed
190
191
192
193
    /**
     * Use DataHandler "afterAllOperations" hook to update or create FE Users
     * in LDAP.
     *
Stefan Busemann's avatar
Stefan Busemann committed
194
     * @param \In2code\Femanager\Domain\Model\User $user
Stefan Busemann's avatar
Stefan Busemann committed
195
     * @return bool
Stefan Busemann's avatar
Stefan Busemann committed
196
     */
197
198
    public function createUser(User $user)
    {
199
200
        $this->persistenceManager->persistAll();
        $myProfileUser = $this->myProfileRepository->findDisabledByUid($user->getUid());
201
        $result = $this->ldapUserCreateUpdateDelete->updateUser($myProfileUser);
202

Stefan Busemann's avatar
Stefan Busemann committed
203
        // TODO: Create log entry if user has been successfully added or throw an exception otherwise
204
        return $result;
Stefan Busemann's avatar
Stefan Busemann committed
205
206
207
208
209
210
    }

    /**
     * Use DataHandler "afterAllOperations" hook to update or create FE Users
     * in LDAP.
     *
Stefan Busemann's avatar
Stefan Busemann committed
211
     * @param \In2code\Femanager\Domain\Model\User $user
212
     * @return bool
Stefan Busemann's avatar
Stefan Busemann committed
213
     */
214
215
    public function updateUser(User $user)
    {
216
        $myProfileUser = $this->myProfileRepository->findDisabledByUid($user->getUid());
217
        $result = $this->ldapUserCreateUpdateDelete->updateUser($myProfileUser);
218
219

        // TODO: Create log entry if user has been successfully updated or throw an exception othwerwise
220
        return $result;
Stefan Busemann's avatar
Stefan Busemann committed
221
222
    }

Stefan Busemann's avatar
Stefan Busemann committed
223
    /**
224
225
226
227
     * @param array $_funcRef
     * @param array $_params
     * @param bool $felogin
     * @return void
Stefan Busemann's avatar
Stefan Busemann committed
228
     */
Stefan Busemann's avatar
Stefan Busemann committed
229
    public function writePassword($_funcRef, $_params, $felogin = false)
230
    {
231
        $feUserUid = (int)$_funcRef['user']['uid'];
232
233

        // set new password
Stefan Busemann's avatar
Stefan Busemann committed
234
        $userData['password'] = $_funcRef['newPasswordUnencrypted'];
Stefan Busemann's avatar
Stefan Busemann committed
235
236
        $createIfNotExists = false;

237
        // @todo add error handling
238
239
240
241
        $objectManager = GeneralUtility::makeInstance(ObjectManager::class);
        $userRepository = $objectManager->get(\In2code\Femanager\Domain\Repository\UserRepository::class);
        $user = $userRepository->findByUid($feUserUid);
        $this->ldapUserCreateUpdateDelete->updateUser($user, $createIfNotExists);
Stefan Busemann's avatar
Stefan Busemann committed
242
243
244
245
246
247
248
249
250
    }

    /**
     * @param string $title
     * @param string $text
     * @param string $color
     */
    protected function sendSlackBotMessage($title, $text, $color = 'notice')
    {
Stefan Busemann's avatar
Stefan Busemann committed
251
        $url = $this->settings['slackbot']['webhook']['url'];
Stefan Busemann's avatar
Stefan Busemann committed
252
        $content = json_encode(array(
Stefan Busemann's avatar
Stefan Busemann committed
253
            'securityToken' => $this->settings['slackbot']['webhook']['securityToken'],
Stefan Busemann's avatar
Stefan Busemann committed
254
255
256
257
258
259
260
261
262
263
264
265
266
            'color' => $color,
            'title' => $title,
            'text' => $text
        ));
        $curl = curl_init($url);
        curl_setopt($curl, CURLOPT_HEADER, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-type: application/json'));
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $content);

        curl_exec($curl);
        curl_close($curl);
Stefan Busemann's avatar
Stefan Busemann committed
267
    }
Stefan Busemann's avatar
Stefan Busemann committed
268

269
270
271
272
    /**
     * @return void
     */
    protected function getTSConfiguration()
Stefan Busemann's avatar
Stefan Busemann committed
273
274
275
276
277
278
279
280
281
    {
        // init ConfigurationManager
        $configurationManager = GeneralUtility::makeInstance('TYPO3\\CMS\\Extbase\\Configuration\\ConfigurationManager');

        // load complete ts
        $tsSettings = $configurationManager->getConfiguration(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FULL_TYPOSCRIPT);

        // remove dots from configuration
        $typoscriptService = GeneralUtility::makeInstance(TypoScriptService::class);
282
        $this->fullTS = $tsSettings;
283
284
        $settings = $typoscriptService->convertTypoScriptArrayToPlainArray($tsSettings);
        $this->settings = $settings['plugin']['tx_t3omy'];
Stefan Busemann's avatar
Stefan Busemann committed
285
286
287
    }

    /**
Stefan Busemann's avatar
Stefan Busemann committed
288
     * @param \In2code\Femanager\Domain\Model\User $user
Stefan Busemann's avatar
Stefan Busemann committed
289
290
     * @return bool
     */
291
292
    protected function sendConfirmationEmail(User $user)
    {
293

294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
        $objectManager = GeneralUtility::makeInstance(ObjectManager::class);

        $femanagerSettings = $this->fullTS['plugin.']['tx_femanager.']['settings.'];
        $sendMailService = $objectManager->get(SendMailService::class);

        $sendMailService->send(
            'CreateUserSecondConfirmation',
            StringUtility::makeEmailArray(
                $femanagerSettings['new.']['email.']['createUserConfirmation.']['sender.']['email.']['value'],
                $femanagerSettings['new.']['email.']['createUserConfirmation.']['sender.']['name.']['value']
            ),
            StringUtility::makeEmailArray($user->getEmail(), $user->getUsername()),
            'typo3.org registration: Personal confirmation needed',
            [
                'user' => $user,
            ],
            $femanagerSettings['new.']['email.']['createUserConfirmation.']
        );
312

Stefan Busemann's avatar
Stefan Busemann committed
313
314
        return true;
    }
315

316
317
318
    /**
     * @return string
     */
319
320
    protected function getLocationDataByIp()
    {
321
        $location = '';
322
323
324
325
326
327
328
        $locationData = file_get_contents('http://geoip.nekudo.com/api/' . $_SERVER['REMOTE_ADDR']);
        if ($locationData !== false) {
            $locationData = json_decode($locationData, true);
        }

        if (!empty($locationData)) {
            if (isset($locationData['error'])) {
329
                $location = 'Location could not retrieved.';
330
331
332
333
334
335
336
337
338
339
            } else {
                if (isset($locationData['country']['name'])) {
                    $location = $locationData['country']['name'];
                }

                if (isset($locationData['city']) && $locationData['city']) {
                    $location .= ', ' . $locationData['city'];
                }
            }
        } else {
340
            $location = 'Empty result from geoip.nekudo.com/api/.';
341
342
        }

343
        return $location;
344
    }
Stefan Busemann's avatar
Stefan Busemann committed
345
}