@ -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 \Runtime Exception ( '' );
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 );
}
}