/** * @test */ public function tokenFromSessionDataIsAvailableForValidateToken() { $sessionToken = '881ffea2159ac72182557b79dc0c723f5a8d20136f9fab56cdd4f8b3a1dbcfcd'; $formName = 'foo'; $action = 'edit'; $formInstanceName = '42'; $tokenId = \TYPO3\CMS\Core\Utility\GeneralUtility::hmac($formName . $action . $formInstanceName . $sessionToken); $this->getBackendUser()->expects($this->atLeastOnce())->method('getSessionData')->with('formSessionToken')->will($this->returnValue($sessionToken)); $this->subject->_call('retrieveSessionToken'); $this->assertTrue($this->subject->validateToken($tokenId, $formName, $action, $formInstanceName)); }
/** * @test */ public function tokenFromSessionDataIsAvailableForValidateToken() { $sessionToken = '881ffea2159ac72182557b79dc0c723f5a8d20136f9fab56cdd4f8b3a1dbcfcd'; $formName = 'foo'; $action = 'edit'; $formInstanceName = '42'; $tokenId = \t3lib_div::hmac($formName . $action . $formInstanceName . $sessionToken); $GLOBALS['BE_USER']->expects($this->atLeastOnce())->method('getSessionData')->with('formSessionToken')->will($this->returnValue($sessionToken)); $this->fixture->retrieveSessionToken(); $this->assertTrue($this->fixture->validateToken($tokenId, $formName, $action, $formInstanceName)); }
/** * If settings are submitted to _POST[DATA], store them * NOTICE: This method is called before the template.php is included. See * bottom of document. */ public function storeIncomingData() { // First check if something is submitted in the data-array from POST vars $d = \TYPO3\CMS\Core\Utility\GeneralUtility::_POST('data'); $columns = $GLOBALS['TYPO3_USER_SETTINGS']['columns']; $beUserId = $GLOBALS['BE_USER']->user['uid']; $storeRec = array(); $fieldList = $this->getFieldsFromShowItem(); if (is_array($d) && $this->formProtection->validateToken((string) \TYPO3\CMS\Core\Utility\GeneralUtility::_POST('formToken'), 'BE user setup', 'edit')) { // UC hashed before applying changes $save_before = md5(serialize($GLOBALS['BE_USER']->uc)); // PUT SETTINGS into the ->uc array: // Reload left frame when switching BE language if (isset($d['lang']) && $d['lang'] != $GLOBALS['BE_USER']->uc['lang']) { $this->languageUpdate = TRUE; } // Reload pagetree if the title length is changed if (isset($d['titleLen']) && $d['titleLen'] !== $GLOBALS['BE_USER']->uc['titleLen']) { $this->pagetreeNeedsRefresh = TRUE; } if ($d['setValuesToDefault']) { // If every value should be default $GLOBALS['BE_USER']->resetUC(); $this->settingsAreResetToDefault = TRUE; } elseif ($d['clearSessionVars']) { foreach ($GLOBALS['BE_USER']->uc as $key => $value) { if (!isset($columns[$key])) { unset($GLOBALS['BE_USER']->uc[$key]); } } $this->tempDataIsCleared = TRUE; } elseif ($d['save']) { // Save all submitted values if they are no array (arrays are with table=be_users) and exists in $GLOBALS['TYPO3_USER_SETTINGS'][columns] foreach ($columns as $field => $config) { if (!in_array($field, $fieldList)) { continue; } if ($config['table']) { if ($config['table'] == 'be_users' && !in_array($field, array('password', 'password2', 'email', 'realName', 'admin'))) { if (!isset($config['access']) || $this->checkAccess($config) && $GLOBALS['BE_USER']->user[$field] !== $d['be_users'][$field]) { $storeRec['be_users'][$beUserId][$field] = $d['be_users'][$field]; $GLOBALS['BE_USER']->user[$field] = $d['be_users'][$field]; } } } if ($config['type'] == 'check') { $GLOBALS['BE_USER']->uc[$field] = isset($d[$field]) ? 1 : 0; } else { $GLOBALS['BE_USER']->uc[$field] = htmlspecialchars($d[$field]); } } // Personal data for the users be_user-record (email, name, password...) // If email and name is changed, set it in the users record: $be_user_data = $d['be_users']; // Possibility to modify the transmitted values. Useful to do transformations, like RSA password decryption if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/setup/mod/index.php']['modifyUserDataBeforeSave'])) { foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/setup/mod/index.php']['modifyUserDataBeforeSave'] as $function) { $params = array('be_user_data' => &$be_user_data); \TYPO3\CMS\Core\Utility\GeneralUtility::callUserFunction($function, $params, $this); } } $this->passwordIsSubmitted = strlen($be_user_data['password']) > 0; $passwordIsConfirmed = $this->passwordIsSubmitted && $be_user_data['password'] === $be_user_data['password2']; // Update the real name: if ($be_user_data['realName'] !== $GLOBALS['BE_USER']->user['realName']) { $GLOBALS['BE_USER']->user['realName'] = $storeRec['be_users'][$beUserId]['realName'] = substr($be_user_data['realName'], 0, 80); } // Update the email address: if ($be_user_data['email'] !== $GLOBALS['BE_USER']->user['email']) { $GLOBALS['BE_USER']->user['email'] = $storeRec['be_users'][$beUserId]['email'] = substr($be_user_data['email'], 0, 80); } // Update the password: if ($passwordIsConfirmed) { $storeRec['be_users'][$beUserId]['password'] = $be_user_data['password2']; $this->passwordIsUpdated = TRUE; } $this->saveData = TRUE; } // Inserts the overriding values. $GLOBALS['BE_USER']->overrideUC(); $save_after = md5(serialize($GLOBALS['BE_USER']->uc)); // If something in the uc-array of the user has changed, we save the array... if ($save_before != $save_after) { $GLOBALS['BE_USER']->writeUC($GLOBALS['BE_USER']->uc); $GLOBALS['BE_USER']->writelog(254, 1, 0, 1, 'Personal settings changed', array()); $this->setupIsUpdated = TRUE; } // If the temporary data has been cleared, lets make a log note about it if ($this->tempDataIsCleared) { $GLOBALS['BE_USER']->writelog(254, 1, 0, 1, $GLOBALS['LANG']->getLL('tempDataClearedLog'), array()); } // Persist data if something has changed: if (count($storeRec) && $this->saveData) { // Make instance of TCE for storing the changes. $tce = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\DataHandling\\DataHandler'); $tce->stripslashes_values = 0; $tce->start($storeRec, array(), $GLOBALS['BE_USER']); // This is so the user can actually update his user record. $tce->admin = 1; // This is to make sure that the users record can be updated even if in another workspace. This is tolerated. $tce->bypassWorkspaceRestrictions = TRUE; $tce->process_datamap(); unset($tce); if (!$this->passwordIsUpdated || count($storeRec['be_users'][$beUserId]) > 1) { $this->setupIsUpdated = TRUE; } } } }
/** * If settings are submitted to _POST[DATA], store them * NOTICE: This method is called before the \TYPO3\CMS\Backend\Template\DocumentTemplate * is included. See bottom of document. * * @see \TYPO3\CMS\Backend\Template\DocumentTemplate */ public function storeIncomingData() { // First check if something is submitted in the data-array from POST vars $d = GeneralUtility::_POST('data'); $columns = $GLOBALS['TYPO3_USER_SETTINGS']['columns']; $beUser = $this->getBackendUser(); $beUserId = $beUser->user['uid']; $storeRec = array(); $fieldList = $this->getFieldsFromShowItem(); if (is_array($d) && $this->formProtection->validateToken((string) GeneralUtility::_POST('formToken'), 'BE user setup', 'edit')) { // UC hashed before applying changes $save_before = md5(serialize($beUser->uc)); // PUT SETTINGS into the ->uc array: // Reload left frame when switching BE language if (isset($d['lang']) && $d['lang'] != $beUser->uc['lang']) { $this->languageUpdate = true; } // Reload pagetree if the title length is changed if (isset($d['titleLen']) && $d['titleLen'] !== $beUser->uc['titleLen']) { $this->pagetreeNeedsRefresh = true; } if ($d['setValuesToDefault']) { // If every value should be default $beUser->resetUC(); $this->settingsAreResetToDefault = true; } elseif ($d['save']) { // Save all submitted values if they are no array (arrays are with table=be_users) and exists in $GLOBALS['TYPO3_USER_SETTINGS'][columns] foreach ($columns as $field => $config) { if (!in_array($field, $fieldList)) { continue; } if ($config['table']) { if ($config['table'] === 'be_users' && !in_array($field, array('password', 'password2', 'passwordCurrent', 'email', 'realName', 'admin', 'avatar'))) { if (!isset($config['access']) || $this->checkAccess($config) && $beUser->user[$field] !== $d['be_users'][$field]) { if ($config['type'] === 'check') { $fieldValue = isset($d['be_users'][$field]) ? 1 : 0; } else { $fieldValue = $d['be_users'][$field]; } $storeRec['be_users'][$beUserId][$field] = $fieldValue; $beUser->user[$field] = $fieldValue; } } } if ($config['type'] === 'check') { $beUser->uc[$field] = isset($d[$field]) ? 1 : 0; } else { $beUser->uc[$field] = htmlspecialchars($d[$field]); } } // Personal data for the users be_user-record (email, name, password...) // If email and name is changed, set it in the users record: $be_user_data = $d['be_users']; // Possibility to modify the transmitted values. Useful to do transformations, like RSA password decryption if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/setup/mod/index.php']['modifyUserDataBeforeSave'])) { foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/setup/mod/index.php']['modifyUserDataBeforeSave'] as $function) { $params = array('be_user_data' => &$be_user_data); GeneralUtility::callUserFunction($function, $params, $this); } } $this->passwordIsSubmitted = (string) $be_user_data['password'] !== ''; $passwordIsConfirmed = $this->passwordIsSubmitted && $be_user_data['password'] === $be_user_data['password2']; // Update the real name: if ($be_user_data['realName'] !== $beUser->user['realName']) { $beUser->user['realName'] = $storeRec['be_users'][$beUserId]['realName'] = substr($be_user_data['realName'], 0, 80); } // Update the email address: if ($be_user_data['email'] !== $beUser->user['email']) { $beUser->user['email'] = $storeRec['be_users'][$beUserId]['email'] = substr($be_user_data['email'], 0, 80); } // Update the password: if ($passwordIsConfirmed) { $currentPasswordHashed = $GLOBALS['BE_USER']->user['password']; $saltFactory = \TYPO3\CMS\Saltedpasswords\Salt\SaltFactory::getSaltingInstance($currentPasswordHashed); if ($saltFactory->checkPassword($be_user_data['passwordCurrent'], $currentPasswordHashed)) { $this->passwordIsUpdated = self::PASSWORD_UPDATED; $storeRec['be_users'][$beUserId]['password'] = $be_user_data['password']; } else { $this->passwordIsUpdated = self::PASSWORD_OLD_WRONG; } } else { $this->passwordIsUpdated = self::PASSWORD_NOT_THE_SAME; } $this->setAvatarFileUid($beUserId, $be_user_data['avatar'], $storeRec); $this->saveData = true; } // Inserts the overriding values. $beUser->overrideUC(); $save_after = md5(serialize($beUser->uc)); // If something in the uc-array of the user has changed, we save the array... if ($save_before != $save_after) { $beUser->writeUC($beUser->uc); $beUser->writelog(254, 1, 0, 1, 'Personal settings changed', array()); $this->setupIsUpdated = true; } // Persist data if something has changed: if (!empty($storeRec) && $this->saveData) { // Make instance of TCE for storing the changes. /** @var DataHandler $dataHandler */ $dataHandler = GeneralUtility::makeInstance(DataHandler::class); $dataHandler->stripslashes_values = false; // This is so the user can actually update his user record. $isAdmin = $beUser->user['admin']; $beUser->user['admin'] = 1; $dataHandler->start($storeRec, array(), $beUser); // This is to make sure that the users record can be updated even if in another workspace. This is tolerated. $dataHandler->bypassWorkspaceRestrictions = true; $dataHandler->process_datamap(); unset($tce); if ($this->passwordIsUpdated === self::PASSWORD_NOT_UPDATED || count($storeRec['be_users'][$beUserId]) > 1) { $this->setupIsUpdated = true; } // Restore admin status after processing $beUser->user['admin'] = $isAdmin; } } }
/** * @test * @expectedException \Exception * @expectedExceptionCode 1442592030 */ public function failingTokenValidationInvokesFailingTokenClosure() { $this->subject->validateToken('foo', 'bar'); }