|
|
@@ -11,146 +11,177 @@ namespace OC\Core\LostPassword\Controller; |
|
|
|
use \OCP\AppFramework\Controller; |
|
|
|
use \OCP\AppFramework\Http\JSONResponse; |
|
|
|
use \OCP\AppFramework\Http\TemplateResponse; |
|
|
|
use \OCP\IURLGenerator; |
|
|
|
use \OCP\IRequest; |
|
|
|
use \OCP\IL10N; |
|
|
|
use \OCP\IConfig; |
|
|
|
use \OCP\IUserSession; |
|
|
|
use \OC\Core\LostPassword\EncryptedDataException; |
|
|
|
|
|
|
|
class LostController extends Controller { |
|
|
|
|
|
|
|
|
|
|
|
protected $urlGenerator; |
|
|
|
protected $userClass; |
|
|
|
protected $userManager; |
|
|
|
protected $defaults; |
|
|
|
protected $l10n; |
|
|
|
protected $from; |
|
|
|
protected $isDataEncrypted; |
|
|
|
|
|
|
|
public function __construct($appName, IRequest $request, IURLGenerator $urlGenerator, $userClass, |
|
|
|
$defaults, $l10n, $from, $isDataEncrypted) { |
|
|
|
protected $config; |
|
|
|
protected $userSession; |
|
|
|
|
|
|
|
public function __construct($appName, |
|
|
|
IRequest $request, |
|
|
|
IURLGenerator $urlGenerator, |
|
|
|
$userManager, |
|
|
|
$defaults, |
|
|
|
IL10N $l10n, |
|
|
|
IConfig $config, |
|
|
|
IUserSession $userSession, |
|
|
|
$from, |
|
|
|
$isDataEncrypted) { |
|
|
|
parent::__construct($appName, $request); |
|
|
|
$this->urlGenerator = $urlGenerator; |
|
|
|
$this->userClass = $userClass; |
|
|
|
$this->userManager = $userManager; |
|
|
|
$this->defaults = $defaults; |
|
|
|
$this->l10n = $l10n; |
|
|
|
$this->from = $from; |
|
|
|
$this->isDataEncrypted = $isDataEncrypted; |
|
|
|
$this->config = $config; |
|
|
|
$this->userSession = $userSession; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Someone wants to reset their password: |
|
|
|
* |
|
|
|
* @PublicPage |
|
|
|
* @NoCSRFRequired |
|
|
|
* |
|
|
|
* |
|
|
|
* @param string $token |
|
|
|
* @param string $uid |
|
|
|
*/ |
|
|
|
public function resetform($token, $uid) { |
|
|
|
// Someone wants to reset their password: |
|
|
|
if($this->checkToken($uid, $token)) { |
|
|
|
return new TemplateResponse( |
|
|
|
'core/lostpassword', |
|
|
|
'resetpassword', |
|
|
|
array( |
|
|
|
'link' => $this->getLink('core.lost.setPassword', $uid, $token), |
|
|
|
'isEncrypted' => $this->isDataEncrypted, |
|
|
|
), |
|
|
|
'guest' |
|
|
|
); |
|
|
|
} else { |
|
|
|
// Someone lost their password |
|
|
|
return new TemplateResponse( |
|
|
|
'core/lostpassword', |
|
|
|
'lostpassword', |
|
|
|
array( |
|
|
|
'isEncrypted' => $this->isDataEncrypted, |
|
|
|
'link' => $this->getLink('core.lost.setPassword', $uid, $token) |
|
|
|
), |
|
|
|
'guest' |
|
|
|
); |
|
|
|
} |
|
|
|
return new TemplateResponse( |
|
|
|
'core/lostpassword', |
|
|
|
'resetpassword', |
|
|
|
array( |
|
|
|
'isEncrypted' => $this->isDataEncrypted, |
|
|
|
'link' => $this->getLink('core.lost.setPassword', $uid, $token), |
|
|
|
), |
|
|
|
'guest' |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* @PublicPage |
|
|
|
* |
|
|
|
* |
|
|
|
* @param string $user |
|
|
|
* @param bool $proceed |
|
|
|
*/ |
|
|
|
public function email($user, $proceed){ |
|
|
|
$response = new JSONResponse(array('status'=>'success')); |
|
|
|
// FIXME: use HTTP error codes |
|
|
|
try { |
|
|
|
$this->sendEmail($user, $proceed); |
|
|
|
} catch (EncryptedDataException $e){ |
|
|
|
$response->setData(array( |
|
|
|
'status' => 'error', |
|
|
|
'encryption' => '1' |
|
|
|
)); |
|
|
|
array('status' => 'error', 'encryption' => '1'); |
|
|
|
} catch (\Exception $e){ |
|
|
|
$response->setData(array( |
|
|
|
'status' => 'error', |
|
|
|
'msg' => $e->getMessage() |
|
|
|
)); |
|
|
|
return array('status' => 'error', 'msg' => $e->getMessage()); |
|
|
|
} |
|
|
|
|
|
|
|
return $response; |
|
|
|
|
|
|
|
return array('status'=>'success'); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* @PublicPage |
|
|
|
*/ |
|
|
|
public function setPassword($token, $uid, $password) { |
|
|
|
$response = new JSONResponse(array('status'=>'success')); |
|
|
|
try { |
|
|
|
if (!$this->checkToken($uid, $token)) { |
|
|
|
throw new \RuntimeException(''); |
|
|
|
throw new \Exception(); |
|
|
|
} |
|
|
|
$userClass = $this->userClass; |
|
|
|
if (!$userClass::setPassword($uid, $password)) { |
|
|
|
throw new \RuntimeException(''); |
|
|
|
|
|
|
|
$user = $this->userManager->get($uid); |
|
|
|
if (!$user->setPassword($uid, $password)) { |
|
|
|
|
|
|
|
throw new \Exception(); |
|
|
|
} |
|
|
|
|
|
|
|
// FIXME: should be added to the all config at some point |
|
|
|
\OC_Preferences::deleteKey($uid, 'owncloud', 'lostpassword'); |
|
|
|
$userClass::unsetMagicInCookie(); |
|
|
|
} catch (Exception $e){ |
|
|
|
$response->setData(array( |
|
|
|
'status' => 'error', |
|
|
|
'msg' => $e->getMessage() |
|
|
|
)); |
|
|
|
$this->userSession->unsetMagicInCookie(); |
|
|
|
|
|
|
|
} catch (\Exception $e){ |
|
|
|
return array('status' => 'error','msg' => $e->getMessage()); |
|
|
|
} |
|
|
|
return $response; |
|
|
|
|
|
|
|
return array('status'=>'success'); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected function sendEmail($user, $proceed) { |
|
|
|
if ($this->isDataEncrypted && $proceed !== 'Yes'){ |
|
|
|
if ($this->isDataEncrypted && !$proceed){ |
|
|
|
throw new EncryptedDataException(); |
|
|
|
} |
|
|
|
|
|
|
|
$userClass = $this->userClass; |
|
|
|
if (!$userClass::userExists($user)) { |
|
|
|
throw new \Exception($this->l10n->t('Couldn’t send reset email. Please make sure your username is correct.')); |
|
|
|
if (!$this->userManager->userExists($user)) { |
|
|
|
throw new \Exception( |
|
|
|
$this->l10n->t('Couldn’t send reset email. Please make sure '. |
|
|
|
'your username is correct.')); |
|
|
|
} |
|
|
|
|
|
|
|
$token = hash('sha256', \OC_Util::generateRandomBytes(30)); |
|
|
|
\OC_Preferences::setValue($user, 'owncloud', 'lostpassword', hash('sha256', $token)); // Hash the token again to prevent timing attacks |
|
|
|
$email = \OC_Preferences::getValue($user, 'settings', 'email', ''); |
|
|
|
|
|
|
|
// Hash the token again to prevent timing attacks |
|
|
|
$this->config->setUserValue( |
|
|
|
$user, 'owncloud', 'lostpassword', hash('sha256', $token) |
|
|
|
); |
|
|
|
|
|
|
|
$email = $this->config->getUserValue($user, 'settings', 'email'); |
|
|
|
|
|
|
|
if (empty($email)) { |
|
|
|
throw new \Exception($this->l10n->t('Couldn’t send reset email because there is no email address for this username. Please contact your administrator.')); |
|
|
|
throw new \Exception( |
|
|
|
$this->l10n->t('Couldn’t send reset email because there is no '. |
|
|
|
'email address for this username. Please ' . |
|
|
|
'contact your administrator.') |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
$link = $this->getLink('core.lost.resetform', $user, $token); |
|
|
|
|
|
|
|
$tmpl = new \OC_Template('core/lostpassword', 'email'); |
|
|
|
$tmpl->assign('link', $link, false); |
|
|
|
$msg = $tmpl->fetchPage(); |
|
|
|
|
|
|
|
try { |
|
|
|
\OC_Mail::send($email, $user, $this->l10n->t('%s password reset', array($this->defaults->getName())), $msg, $this->from, $this->defaults->getName()); |
|
|
|
\OC_Mail::send($email, $user, $this->l10n->t( |
|
|
|
'%s password reset', |
|
|
|
array( |
|
|
|
$this->defaults->getName())), |
|
|
|
$msg, |
|
|
|
$this->from, |
|
|
|
$this->defaults->getName() |
|
|
|
)); |
|
|
|
} catch (\Exception $e) { |
|
|
|
throw new \Exception( $this->l10n->t('Couldn’t send reset email. Please contact your administrator.')); |
|
|
|
throw new \Exception($this->l10n->t('Couldn’t send reset email. ' . |
|
|
|
'Please contact your administrator.')); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected function getLink($route, $user, $token){ |
|
|
|
$parameters = array( |
|
|
|
'token' => $token, |
|
|
|
'token' => $token, |
|
|
|
'uid' => $user |
|
|
|
); |
|
|
|
$link = $this->urlGenerator->linkToRoute($route, $parameters); |
|
|
|
return $this->urlGenerator->getAbsoluteUrl($link); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected function checkToken($user, $token) { |
|
|
|
return \OC_Preferences::getValue($user, 'owncloud', 'lostpassword') === hash('sha256', $token); |
|
|
|
return $this->config->getUserValue( |
|
|
|
$user, 'owncloud', 'lostpassword' |
|
|
|
) === hash('sha256', $token); |
|
|
|
} |
|
|
|
|
|
|
|
} |