Overview

Packages

  • CONTENIDO
  • Core
    • Authentication
    • Backend
    • Cache
    • CEC
    • Chain
    • ContentType
    • Database
    • Debug
    • Exception
    • Frontend
      • Search
      • URI
      • Util
    • GenericDB
      • Model
    • GUI
      • HTML
    • I18N
    • LayoutHandler
    • Log
    • Security
    • Session
    • Util
    • Validation
    • Versioning
    • XML
  • Module
    • ContentRssCreator
    • ContentSitemapHtml
    • ContentSitemapXml
    • ContentUserForum
    • NavigationTop
    • ScriptCookieDirective
  • mpAutoloaderClassMap
  • None
  • Plugin
    • ContentAllocation
    • CronjobOverview
    • FormAssistant
    • FrontendLogic
    • FrontendUsers
    • Linkchecker
    • ModRewrite
    • Newsletter
    • Repository
      • FrontendNavigation
      • KeywordDensity
    • SearchSolr
    • SmartyWrapper
    • UrlShortener
    • UserForum
    • Workflow
  • PluginManager
  • Setup
    • Form
    • GUI
    • Helper
      • Environment
      • Filesystem
      • MySQL
      • PHP
    • UpgradeJob
  • Smarty
    • Cacher
    • Compiler
    • Config
    • Debug
    • PluginsBlock
    • PluginsFilter
    • PluginsFunction
    • PluginsInternal
    • PluginsModifier
    • PluginsModifierCompiler
    • PluginsShared
    • Security
    • Template
    • TemplateResources
  • Swift
    • ByteStream
    • CharacterStream
    • Encoder
    • Events
    • KeyCache
    • Mailer
    • Mime
    • Plugins
    • Transport

Classes

  • Swift_FailoverTransport
  • Swift_LoadBalancedTransport
  • Swift_MailTransport
  • Swift_Plugins_Loggers_ArrayLogger
  • Swift_Plugins_Loggers_EchoLogger
  • Swift_SendmailTransport
  • Swift_SmtpTransport
  • Swift_Transport_AbstractSmtpTransport
  • Swift_Transport_Esmtp_Auth_CramMd5Authenticator
  • Swift_Transport_Esmtp_Auth_LoginAuthenticator
  • Swift_Transport_Esmtp_Auth_PlainAuthenticator
  • Swift_Transport_Esmtp_AuthHandler
  • Swift_Transport_EsmtpTransport
  • Swift_Transport_FailoverTransport
  • Swift_Transport_LoadBalancedTransport
  • Swift_Transport_MailTransport
  • Swift_Transport_SendmailTransport
  • Swift_Transport_SimpleMailInvoker
  • Swift_Transport_StreamBuffer

Interfaces

  • Swift_Plugins_Logger
  • Swift_Plugins_Pop_Pop3Exception
  • Swift_Transport
  • Swift_Transport_Esmtp_Authenticator
  • Swift_Transport_EsmtpHandler
  • Swift_Transport_IoBuffer
  • Swift_Transport_MailInvoker
  • Swift_Transport_SmtpAgent
  • Swift_TransportException
  • Overview
  • Package
  • Function
  • Todo
  • Download
  1: <?php
  2: /**
  3:  * This file contains the the password request class.
  4:  *
  5:  * @package Core
  6:  * @subpackage Backend
  7:  * @version SVN Revision $Rev:$
  8:  *
  9:  * @author Timo Trautmann
 10:  * @copyright four for business AG <www.4fb.de>
 11:  * @license http://www.contenido.org/license/LIZENZ.txt
 12:  * @link http://www.4fb.de
 13:  * @link http://www.contenido.org
 14:  */
 15: 
 16: defined('CON_FRAMEWORK') || die('Illegal call: Missing framework initialization - request aborted.');
 17: 
 18: /**
 19:  * Class for handling passwort recovery for backend users.
 20:  * If a user has set his e-mail address, this class
 21:  * generates a new Password for user and submits to his e-mail address.
 22:  * Submitting a new Password is
 23:  * only possible every 30 minutes Mailsender, Mailsendername and Mailserver are
 24:  * set into system properties.
 25:  * There it is also possible to deactivate this feature.
 26:  *
 27:  * @package Core
 28:  * @subpackage Backend
 29:  */
 30: class cPasswordRequest {
 31: 
 32:     /**
 33:      * The CONTENIDO database object
 34:      *
 35:      * @var cDb
 36:      */
 37:     protected $_db;
 38: 
 39:     /**
 40:      * The CONTENIDO configuration array
 41:      *
 42:      * @var array
 43:      */
 44:     protected $_cfg;
 45: 
 46:     /**
 47:      * The CONTENIDO template object
 48:      *
 49:      * @var cTemplate
 50:      */
 51:     protected $_tpl;
 52: 
 53:     /**
 54:      * Username of user which requests password
 55:      *
 56:      * @var string
 57:      */
 58:     protected $_username;
 59: 
 60:     /**
 61:      * E-mail address of user which requests password
 62:      *
 63:      * @var string
 64:      */
 65:     protected $_email;
 66: 
 67:     /**
 68:      * Time in minutes after which user is allowed to request a new password
 69:      *
 70:      * @var int
 71:      */
 72:     protected $_reloadTime;
 73: 
 74:     /**
 75:      * Length of validation token, which is generated automatically
 76:      *
 77:      * @var int
 78:      */
 79:     protected $_tokenLength;
 80: 
 81:     /**
 82:      * Defines if passwort request is enabled or disabled.
 83:      * Default: This feature is enabled
 84:      *
 85:      * @var bool
 86:      */
 87:     protected $_isEnabled;
 88: 
 89:     /**
 90:      * E-mail address of the sender
 91:      *
 92:      * @var string
 93:      */
 94:     protected $_sendermail;
 95: 
 96:     /**
 97:      * Name of the sender
 98:      *
 99:      * @var string
100:      */
101:     protected $_sendername;
102: 
103:     /**
104:      * Constructor of RequestPassword initializes class variables
105:      *
106:      * @param cDb $db The CONTENIDO database object
107:      * @param array $cfg The CONTENIDO configuration array
108:      */
109:     public function __construct($db, $cfg) {
110:         // generate new dbobject, if it does not exist
111:         if (!is_object($db)) {
112:             $this->_db = cRegistry::getDb();
113:         } else {
114:             $this->_db = $db;
115:         }
116: 
117:         // init class variables
118:         $this->_cfg = $cfg;
119:         $this->_tpl = new cTemplate();
120:         $this->_username = '';
121:         $this->_email = '';
122: 
123:         // set reload to 4 hours (60*4 minutes)
124:         $this->_reloadTime = 240;
125: 
126:         // set token length to 14 chars
127:         $this->_tokenLength = 14;
128: 
129:         // get systemproperty, which definies if password request is enabled
130:         // (true) or disabled (false) : default to enabled
131:         $sEnable = getSystemProperty('pw_request', 'enable');
132:         if ($sEnable == 'false') {
133:             $this->_isEnabled = false;
134:         } else {
135:             $this->_isEnabled = true;
136:         }
137: 
138:         // get systemproperty for senders mail and validate mail address, if not
139:         // set use standard sender
140:         $sendermail = getSystemProperty('system', 'mail_sender');
141:         if (preg_match("/^.+@.+\.([A-Za-z0-9\-_]{1,20})$/", $sendermail)) {
142:             $this->_sendermail = $sendermail;
143:         } else {
144:             $this->_sendermail = 'info@contenido.org';
145:         }
146: 
147:         // get systemproperty for senders name, if not set use CONTENIDO Backend
148:         $sendername = getSystemProperty('system', 'mail_sender_name');
149:         if ($sendername != '') {
150:             $this->_sendername = $sendername;
151:         } else {
152:             $this->_sendername = 'CONTENIDO Backend';
153:         }
154: 
155:         // show form if password reset is wished
156:         // if feature is not enabled, do nothing
157:         if (true === $this->_isEnabled) {
158:             // check if confirmation link from mail used
159:             if (isset($_GET['pw_reset'])
160:             && '' !== $_GET['pw_reset']) {
161:                 // check if requests found
162:                 $aRequests = $this->_getCurrentRequests();
163:                 if (count($aRequests) > 0) {
164:                     // check if form with username and new password was filled out
165:                     if (false === isset($_POST['user_name'])
166:                     || false === isset($_POST['user_pw'])
167:                     || false === isset($_POST['user_pw_repeat'])) {
168:                         // show form to set new password
169:                         $this->renderNewPwForm();
170:                     } else {
171:                         // do validation checks then set new password for user in database
172:                         $this->_handleResetPw();
173:                     }
174:                 }
175:             }
176:         }
177:     }
178: 
179:     /**
180:      * Function displays form for password request, if
181:      * password is submitted this function also starts the
182:      * passwort reset request and sending process
183:      *
184:      * @param bool $return Return or print template
185:      * @return string rendered HTML code
186:      */
187:     public function renderForm($return = false) {
188:         // if feature is not enabled, do nothing
189:         if (!$this->_isEnabled) {
190:             return '';
191:         }
192: 
193:         $message = '';
194: 
195:         // if form is sumbitted call function handleNewPassword() and set
196:         // submitted username to class variable $sUsername
197:         if (isset($_POST['action']) && $_POST['action'] == 'request_pw') {
198:             // avoid SQL-Injection, first check if submitted vars are escaped
199:             // automatically
200:             $this->_username = $_POST['request_username'];
201: 
202:             $message = $this->_handleNewPassword();
203:             // if form is submitted, show corresponding password request layer
204:             $this->_tpl->set('s', 'JS_CALL', 'showRequestLayer();');
205:         } else {
206:             // by default request layer is invisible so do nothing
207:             $this->_tpl->set('s', 'JS_CALL', '');
208:         }
209: 
210:         // generate new form
211:         $form = new cHTMLForm('request_pw', 'index.php', 'post');
212: 
213:         // generate input for username
214:         $inputUsername = new cHTMLTextbox('request_username', stripslashes($_POST['request_username']), '', '', 'request_username');
215:         $inputUsername->setStyle('width:215px;');
216: 
217:         // set request action and current language
218:         $form->setVar('action', 'request_pw');
219:         $form->setVar('belang', $GLOBALS['belang']);
220: 
221:         // generate submitbutton and fill the form
222:         $form->setContent('<input class="password_request_input" type="image" src="images/submit.gif" alt="' . i18n('Submit') . '" title="' . i18n('Submit') . '">' . $inputUsername->render());
223:         $this->_tpl->set('s', 'FORM', $form->render());
224:         $this->_tpl->set('s', 'MESSAGE', $message);
225:         $this->_tpl->set('s', 'LABEL', i18n('Please enter your login') . ':');
226: 
227:         // if handleNewPassword() returns a message, display it
228:         return $this->_tpl->generate($this->_cfg['path']['contenido'] . $this->_cfg['path']['templates'] . $this->_cfg['templates']['request_password'], $return);
229:     }
230: 
231:     /**
232:      * function to display form to set new password for user
233:      */
234:     public function renderNewPwForm() {
235:         if (isset($_POST['action']) && $_POST['action'] == 'reset_pw') {
236:             $this->_username = $_POST['request_username'];
237: 
238:             $message = $this->_handleNewPassword();
239:             // do not show password reset form
240:             $this->_tpl->set('s', 'JS_CALL', '');
241:         } else {
242:             // show password reset form using JavaScript
243:             $this->_tpl->set('s', 'JS_CALL', 'showResetLayer();');
244:         }
245: 
246:         $msg = i18n('You may now set a new password');
247:         $this->_tpl->set('s', 'RESET_LABEL', $msg);
248: 
249:         // insert form with username, password and password repeat fields
250:         $form = new cHTMLForm('reset_form', htmlentities(cRegistry::getBackendUrl()) . '?pw_reset=' . $_GET['pw_reset']);
251: 
252:         $fields = array();
253:         $userNameLbl = new cHTMLDiv(new cHTMLLabel(i18n('User name') . ': ', 'user_name'));
254:         $userNameBox = new cHTMLTextbox('user_name');
255:         $userNameBox->removeAttribute('size');
256:         $userNameBox = new cHTMLDiv($userNameBox);
257: 
258:         $userPwLbl = new cHTMLLabel(i18n('New password') . ': ', 'user_pw');
259:         $userPwBox = new cHTMLTextbox('user_pw');
260:         $userPwBox->setAttribute('type', 'password');
261:         $userPwBox->removeAttribute('size');
262:         $userPwBox = new cHTMLDiv($userPwBox);
263: 
264:         $userPwRepeatLbl = new cHTMLLabel(i18n('Confirm new password'), 'user_pw_repeat');
265:         $userPwRepeatBox = new cHTMLTextbox('user_pw_repeat');
266:         $userPwRepeatBox->setAttribute('type', 'password');
267:         $userPwRepeatBox->removeAttribute('size');
268: 
269:         $sendBtn = new cHTMLButton('submit');
270:         $sendBtn->setAttribute('type', 'image');
271:         $sendBtn->setAttribute('src', 'images/submit.gif');
272:         $sendBtn->setAttribute('alt', i18n('Submit'));
273:         $sendBtn->setAttribute('title', i18n('Submit'));
274: 
275:         $sendBtn->removeAttribute('value');
276:         $form->setContent(array($userNameLbl, $userNameBox, $userPwLbl, $userPwBox, $userPwRepeatLbl, $userPwRepeatBox, $sendBtn));
277: 
278:         $this->_tpl->set('s', 'RESET_MESSAGE', '');
279: 
280:         $this->_tpl->set('s', 'RESET_FORM', $form->render());
281:     }
282: 
283:     /**
284:      * Getter function to obtain an array of all current user password reset requests
285:      */
286:     protected function _getCurrentRequests() {
287:         $oApiUserPasswordRequest = new cApiUserPasswordRequestCollection();
288: 
289:         return $oApiUserPasswordRequest->fetchCurrentRequests();
290:     }
291: 
292:     /**
293:      * Function checks password request for errors and sends a mail using
294:      * _submitMail() in case of valid requests
295:      *
296:      * @return string
297:      */
298:     protected function _handleNewPassword() {
299:         // notification message, which is returned to caller
300:         $message = '';
301: 
302:         // check if requested username exists, also get email and timestamp when
303:         // user last requests a new password (last_pw_request)
304: //         $ocApiUser = new cApiUser(cSecurity::toInteger($this->_username));
305:         $sql = "SELECT username, email FROM " . $this->_cfg['tab']['user'] . "
306:                  WHERE username = '" . $this->_db->escape($this->_username) . "'
307:                  AND (valid_from <= NOW() OR valid_from = '0000-00-00 00:00:00' OR valid_from IS NULL)
308:                  AND (valid_to >= NOW() OR valid_to = '0000-00-00 00:00:00' OR valid_to IS NULL)";
309: 
310:         $this->_db->query($sql);
311:         if ($this->_db->nextRecord() && md5($this->_username) == md5($this->_db->f('username'))) {
312:             // by default user is allowed to request new password
313:             $isAllowed = true;
314: 
315:             // we need latest password request for timelimit comparison
316:             $lastPwRequest = '0000-00-00 00:00:00';
317: 
318:             // check if user has already used max amount of reset requests
319:             $oApiUser = new cApiUser();
320:             // try to load user by name
321:             // this should always work because username in database already confirmed
322:             if (false === $oApiUser->loadBy('username', $this->_username)) {
323:                 $isAllowed = false;
324:                 $message = i18n('New password was submitted to your e-mail address.');
325:             } else {
326:                 $oApiPasswordRequestCol = new cApiUserPasswordRequestCollection();
327:                 $requests = $oApiPasswordRequestCol->fetchAvailableRequests();
328: 
329:                 // do maintainance for all user password requests
330:                 foreach ($requests as $oApiUserPasswordRequest) {
331:                     // get time of password reset request
332:                     $reqTime = $oApiUserPasswordRequest->get('request');
333: 
334:                     // if $reqTime is newer than $lastPwRequest then use this as new last password request time
335:                     if (strtotime($lastPwRequest) < strtotime($reqTime)
336:                     && $this->_db->f($oApiUser->primaryKey) === $oApiUser->get($oApiUser->primaryKey)) {
337:                         $lastPwRequest = $reqTime;
338:                     }
339: 
340:                     // check if password request is too old and considered outdated
341:                     // by default 1 day old requests are outdated
342:                     if (false === ($outdatedStr = getEffectiveSetting('pw_request', 'outdated_threshold', false))
343:                     || '' === $outdatedStr) {
344:                         $outdatedStr = '-1 day';
345:                     }
346:                     // convert times to DateTime objects for comparison
347:                     // force all data to be compared using UTC timezone
348:                     $outdated = new DateTime('now', new DateTimeZone('UTC'));
349:                     $outdated->modify($outdatedStr);
350:                     $expiration = new DateTime($oApiUserPasswordRequest->get('expiration'), new DateTimeZone('UTC'));
351:                     if (false === $oApiUserPasswordRequest->get('expiration')
352:                     || '' === $oApiUserPasswordRequest->get('expiration')
353:                     || $expiration < $outdated) {
354:                         // delete password request as it is considered outdated
355:                         $oApiPasswordRequestCol->delete($oApiUserPasswordRequest->get($oApiUserPasswordRequest->primaryKey));
356:                     }
357:                 }
358: 
359:                 // get all password reset requests related to entered username in form
360:                 $uid = $oApiUser->get($oApiUser->primaryKey);
361:                 $requests = $oApiPasswordRequestCol->fetchAvailableRequests($uid);
362: 
363:                 // get amount of max password reset requests
364:                 if (false === ($resetThreshold = getEffectiveSetting('pw_request', 'reset_threshold', false))
365:                 || '' === $resetThreshold) {
366:                     // use 4 as default value
367:                     $resetThreshold = 4;
368:                 }
369: 
370:                 // check if there are more than allowed number of password requests for user
371:                 if (count($requests) > $resetThreshold) {
372:                     $isAllowed = false;
373:                     $message = i18n('Too many password reset requests. You may wait before requesting a new password.');
374:                 }
375:                 unset($requests);
376:             }
377: 
378:             // store users mail address to class variable
379:             $this->_email = $this->_db->f('email');
380: 
381:             // check if there is a correct last request date
382:             if (preg_match('/^(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})$/', $lastPwRequest, $aMatches)) {
383:                 $lastRequest = mktime($aMatches[4], $aMatches[5], $aMatches[6], $aMatches[2], $aMatches[3], $aMatches[1]);
384: 
385:                 // check if this last request is longer ago than timelimit.
386:                 if ((time() - $lastRequest) < (60 * $this->_reloadTime)) {
387:                     // user is not allowed to request new password, he has to wait
388:                     $isAllowed = false;
389:                     $message = sprintf(i18n('Password requests are allowed every %s minutes.'), $this->_reloadTime);
390:                 }
391:             }
392: 
393:             $this->_username = stripslashes($this->_username);
394: 
395: 
396:             // check if syntax of users mail address is correct and there is no
397:             // standard mail address like admin_kunde@IhreSite.de or
398:             // sysadmin@IhreSite.de
399:             if ((!preg_match("/^.+@.+\.([A-Za-z0-9\-_]{1,20})$/", $this->_email) || $this->_email == 'sysadmin@IhreSite.de' || $this->_email == 'admin_kunde@IhreSite.de') && $isAllowed) {
400:                 $isAllowed = false;
401:                 // $sMessage = i18n('The requested user has no valid e-mail
402:                 // address. Submitting new password is not possible. Please
403:                 // contact your system- administrator for further support.');
404:                 $message = i18n('No matching data found. Please contact your system administrator.');
405:             }
406: 
407:             // if there are no errors, call function _generateToken(), else wait
408:             // a while, then return error message
409:             if ($isAllowed) {
410:                 // generate a new token
411:                 $token = $this->_generateToken();
412: 
413:                 // how long should the password reset request be valid?
414:                 // use 4 hours as expiration time
415:                 $expiration = new DateTime('+4 hour', new DateTimeZone('UTC'));
416: 
417:                 if (false !== $token
418:                 && false !== $this->_safePwResetRequest($token, $expiration)) {
419:                     $this->_submitMail($token);
420:                     $message = i18n('New password was submitted to your e-mail address.');
421:                 } else {
422:                     $message = i18n('An unknown problem occurred. Please contact your system administrator.');
423:                 }
424:             } else {
425:                 sleep(5);
426:             }
427:         } else {
428:             // sleep a while, then return error message
429:             // $sMessage = i18n('This user does not exist.');
430:             $message = i18n('No matching data found. Please contact your system administrator.');
431:             sleep(5);
432:         }
433:         return $message;
434:     }
435: 
436:     /**
437:      * Function checks password reset request for errors and sets a new password in case there is no error
438:      */
439:     protected function _handleResetPw() {
440:         $this->_tpl->set('s', 'JS_CALL', 'showResetLayer();');
441:         $username = (string) $_POST['user_name'];
442:         $pw = (string) $_POST['user_pw'];
443:         $pwRepeat = (string) $_POST['user_pw_repeat'];
444: 
445:         if (0 === strlen($username)) {
446:             $this->_tpl->set('s', 'RESET_MESSAGE', i18n('Username can\'t be empty'));
447:             $this->_tpl->set('s', 'RESET_LABEL', '');
448:             $this->renderNewPwForm();
449:             return;
450:         }
451:         if ($pw !== $pwRepeat) {
452:             $this->_tpl->set('s', 'RESET_MESSAGE', i18n('Passwords don\'t match'));
453:             $this->_tpl->set('s', 'RESET_LABEL', '');
454:             $this->renderNewPwForm();
455:             return;
456:         }
457:         if ((string) $_POST['user_pw'] === (string) $_GET['pw_reset']) {
458:             $this->_tpl->set('s', 'RESET_MESSAGE', i18n('You may not use the confirmation token as password'));
459:             $this->_tpl->set('s', 'RESET_LABEL', '');
460:             $this->renderNewPwForm();
461:             return;
462:         }
463: 
464:         // pass data to cApiUser class
465:         $oApiUser = new cApiUser();
466:         $oApiUser->loadUserByUsername($username);
467:         // check if user exists
468:         if (false === $oApiUser->isLoaded()) {
469:             // present same message as if it worked
470:             // so we do not give information whether a user exists
471:             $this->_tpl->set('s', 'RESET_MESSAGE', i18n('New password has been set.'));
472:             $this->_tpl->set('s', 'RESET_LABEL', '');
473:             $this->_tpl->set('s', 'RESET_FORM', '');
474:             return;
475:         }
476: 
477:         $oPasswordRequest = new cApiUserPasswordRequestCollection();
478:         // check if username matches validation token
479:         // user alice must not be able to set password for a different user bob
480: 
481:         // get available requests for all users
482:         if (null === ($requests = $this->_getCurrentRequests())) {
483:             // no password requests found but do not tell user
484:             $this->_tpl->set('s', 'RESET_MESSAGE', i18n('New password has been set.'));
485:             $this->_tpl->set('s', 'RESET_LABEL', '');
486:             $this->_tpl->set('s', 'RESET_FORM', '');
487:             return;
488:         }
489: 
490:         // check if passed get parameter matches request for one user
491:         $validUser = false;
492:         foreach ($requests as $request) {
493:             // match validation token against database password reset entry
494:             if ($request->get('validation_token') === $_GET['pw_reset'])
495:             {
496:                 // we found the used token
497:                 if ($oApiUser->get($oApiUser->primaryKey) === $request->get($oApiUser->primaryKey)) {
498:                     // user entered in form matches user related to validation token
499:                     $validUser = true;
500:                 }
501:             }
502:         }
503:         if (false === $validUser) {
504:             // no password requests found for this user
505:             // but let the user think it could set password for different user
506:             $this->_tpl->set('s', 'RESET_MESSAGE', i18n('New password has been set.'));
507:             $this->_tpl->set('s', 'RESET_LABEL', '');
508:             $this->_tpl->set('s', 'RESET_FORM', '');
509:             return;
510:         }
511: 
512:         // try to set password
513:         $res = $oApiUser->setPassword($pw);
514: 
515:         $msg = '';
516:         // check if password was accepted by cApiUser class
517:         if (cApiUser::PASS_OK !== $res) {
518:             // password not accepted, present error message from cApiUser class to end user
519:             $msg = cApiUser::getErrorString($res);
520:             $this->_tpl->set('s', 'RESET_MESSAGE', $msg);
521:             $this->_tpl->set('s', 'RESET_LABEL', '');
522:             $this->renderNewPwForm();
523:             return;
524:         }
525:         // check if new password can be saved for user
526:         if (false !== $oApiUser->store()) {
527:             $this->_tpl->set('s', 'RESET_LABEL', '');
528:             $this->_tpl->set('s', 'RESET_FORM', '');
529:             // remove all password requests for this user from database
530:             $oPasswordRequest->deleteByUserId($oApiUser->get($oApiUser->primaryKey));
531:             $msg = i18n('New password has been set.');
532:         } else {
533:             // password could not be saved
534:             $msg = i18n('An unknown problem occurred. Please contact your system administrator.');
535:         }
536: 
537:         // display message in form
538:         $this->_tpl->set('s', 'RESET_MESSAGE', $msg);
539:     }
540: 
541:     /**
542:      * Save request into db for future validity check
543:      * @param string $token Token used to check for validity at user confirmation part
544:      * @param DateTime Expiration time of reset request validity
545:      * @return bool whether password request could be safed successfully
546:      */
547:     protected function _safePwResetRequest($token, DateTime $expiration) {
548:         $oUserPwRequestCol = new cApiUserPasswordRequestCollection();
549:         $oUserPwRequest = $oUserPwRequestCol->createNewItem();
550: 
551:         // set request data
552:         $requestTime = new DateTime('now', new DateTimeZone('UTC'));
553:         $oApiUser = new cApiUser();
554:         $oApiUser->loadBy('username', $this->_username);
555: 
556:         $oUserPwRequest->set($oApiUser->primaryKey, $oApiUser->get($oApiUser->primaryKey));
557:         $oUserPwRequest->set('request', $requestTime->format('Y-m-d H:i:s'));
558:         $oUserPwRequest->set('expiration', $expiration->format('Y-m-d H:i:s'));
559:         $oUserPwRequest->set('validation_token', $token);
560: 
561:         // save request data
562:         return $oUserPwRequest->store();
563:     }
564: 
565:     /**
566:      * Function submits new password to users mail address
567:      *
568:      * @param string $token The token used to authorise password change
569:      */
570:     protected function _submitMail($token) {
571:         $cfg = cRegistry::getConfig();
572: 
573:         $token = (string) $token;
574: 
575:         // get translation for mailbody and insert username and new password
576:         $msg = i18n("Dear CONTENIDO-User %s,\n\nA request to change your password for Content Management System CONTENIDO was made. ");
577:         $msg .= i18n("Use the following URL to confirm the password change:\n\n");
578:         $msg .= cRegistry::getBackendUrl() . '?pw_reset=';
579:         $msg .= i18n("%s\n\nBest regards\n\nYour CONTENIDO sysadmin");
580:         $mailBody = sprintf($msg, $this->_username, $token);
581: 
582:         $mailer = new cMailer();
583:         $from = array(
584:             $this->_sendermail => $this->_sendername
585:         );
586: 
587:         // Decoding and encoding for charsets (without UTF-8)
588:         if ($cfg['php_settings']['default_charset'] != 'UTF-8') {
589:             $subject = utf8_encode(conHtmlEntityDecode(stripslashes(i18n('Your new password for CONTENIDO Backend')), '', $cfg['php_settings']['default_charset']));
590:             $body = utf8_encode(conHtmlEntityDecode($mailBody, '', $cfg['php_settings']['default_charset']));
591:         } else {
592:             $subject = conHtmlEntityDecode(stripslashes(i18n('Your new password for CONTENIDO Backend')));
593:             $body = conHtmlEntityDecode($mailBody);
594:         }
595: 
596:         $mailer->sendMail($from, $this->_email, $subject, $body);
597:     }
598: 
599:     /**
600:      * Function generates new token
601:      *
602:      * @return string The new token
603:      */
604:     protected function _generateToken() {
605:         // possible chars which were used in password
606:         $chars = "ABCDEFGHJKLMNOPQRSTUVWXYZabcdefghjkmnopqrstuvwxyz123456789";
607: 
608:         $password = "";
609: 
610:         // for each character of token choose one from $sChars randomly
611:         for ($i = 0; $i < $this->_tokenLength; $i++) {
612:             $password .= $chars[rand(0, strlen($chars))];
613:         }
614: 
615:         return $password;
616:     }
617: }
618: 
CMS CONTENIDO 4.9.7 API documentation generated by ApiGen