Make sure access/email/password tokens are valid

This commit is contained in:
Toby Zerner 2015-08-06 15:04:38 +09:30
parent dd39a6b36b
commit a553ac2b92
7 changed files with 29 additions and 4 deletions

View File

@ -27,7 +27,7 @@ class LoginWithCookieAndCheckAdmin implements MiddlewareInterface
public function __invoke(Request $request, Response $response, callable $out = null) public function __invoke(Request $request, Response $response, callable $out = null)
{ {
if (($token = array_get($request->getCookieParams(), 'flarum_remember')) && if (($token = array_get($request->getCookieParams(), 'flarum_remember')) &&
($accessToken = AccessToken::where('id', $token)->first()) && ($accessToken = AccessToken::valid($token)) &&
$accessToken->user->isAdmin() $accessToken->user->isAdmin()
) { ) {
$this->app->instance('flarum.actor', $accessToken->user); $this->app->instance('flarum.actor', $accessToken->user);

View File

@ -1,6 +1,7 @@
<?php namespace Flarum\Api; <?php namespace Flarum\Api;
use Flarum\Core\Model; use Flarum\Core\Model;
use DateTime;
/** /**
* @todo document database columns with @property * @todo document database columns with @property
@ -43,6 +44,17 @@ class AccessToken extends Model
return $token; return $token;
} }
/**
* Get the given token only if it is valid.
*
* @param string $token
* @return static|null
*/
public static function valid($token)
{
return static::where('id', $token)->where('expires_at', '>', new DateTime)->first();
}
/** /**
* Define the relationship with the owner of this access token. * Define the relationship with the owner of this access token.
* *

View File

@ -34,7 +34,7 @@ class LoginWithHeader implements MiddlewareInterface
$header = $request->getHeaderLine('authorization'); $header = $request->getHeaderLine('authorization');
if (starts_with($header, $this->prefix) && if (starts_with($header, $this->prefix) &&
($token = substr($header, strlen($this->prefix))) && ($token = substr($header, strlen($this->prefix))) &&
($accessToken = AccessToken::where('id', $token)->first()) ($accessToken = AccessToken::valid($token))
) { ) {
$this->app->instance('flarum.actor', $user = $accessToken->user); $this->app->instance('flarum.actor', $user = $accessToken->user);

View File

@ -5,6 +5,7 @@ use Flarum\Events\UserWillBeSaved;
use Flarum\Core\Support\DispatchesEvents; use Flarum\Core\Support\DispatchesEvents;
use Flarum\Core\Exceptions\InvalidConfirmationTokenException; use Flarum\Core\Exceptions\InvalidConfirmationTokenException;
use Flarum\Core\Users\EmailToken; use Flarum\Core\Users\EmailToken;
use DateTime;
class ConfirmEmailHandler class ConfirmEmailHandler
{ {
@ -32,7 +33,7 @@ class ConfirmEmailHandler
{ {
$token = EmailToken::find($command->token); $token = EmailToken::find($command->token);
if (! $token) { if (! $token || $token->created_at < new DateTime('-1 day')) {
throw new InvalidConfirmationTokenException; throw new InvalidConfirmationTokenException;
} }

View File

@ -1,12 +1,14 @@
<?php namespace Flarum\Forum\Actions; <?php namespace Flarum\Forum\Actions;
use Flarum\Api\Client; use Flarum\Api\Client;
use Flarum\Api\AccessToken;
use Flarum\Events\UserLoggedIn; use Flarum\Events\UserLoggedIn;
use Flarum\Core\Users\UserRepository; use Flarum\Core\Users\UserRepository;
use Flarum\Support\Action; use Flarum\Support\Action;
use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ServerRequestInterface as Request;
use Zend\Diactoros\Response\EmptyResponse; use Zend\Diactoros\Response\EmptyResponse;
use Zend\Diactoros\Response\JsonResponse; use Zend\Diactoros\Response\JsonResponse;
use DateTime;
class LoginAction extends Action class LoginAction extends Action
{ {
@ -47,6 +49,10 @@ class LoginAction extends Action
// response so we can look at the response code. For now if there isn't // response so we can look at the response code. For now if there isn't
// any useful data we just assume it's a 401. // any useful data we just assume it's a 401.
if (isset($data->userId)) { if (isset($data->userId)) {
// Extend the token's expiry to 2 weeks so that we can set a
// remember cookie
AccessToken::where('id', $data->token)->update(['expires_at' => new DateTime('+2 weeks')]);
event(new UserLoggedIn($this->users->findOrFail($data->userId), $data->token)); event(new UserLoggedIn($this->users->findOrFail($data->userId), $data->token));
return $this->withRememberCookie( return $this->withRememberCookie(

View File

@ -2,7 +2,9 @@
use Flarum\Core\Users\PasswordToken; use Flarum\Core\Users\PasswordToken;
use Flarum\Support\HtmlAction; use Flarum\Support\HtmlAction;
use Flarum\Core\Exceptions\InvalidConfirmationTokenException;
use Psr\Http\Message\ServerRequestInterface as Request; use Psr\Http\Message\ServerRequestInterface as Request;
use DateTime;
class ResetPasswordAction extends HtmlAction class ResetPasswordAction extends HtmlAction
{ {
@ -17,6 +19,10 @@ class ResetPasswordAction extends HtmlAction
$token = PasswordToken::findOrFail($token); $token = PasswordToken::findOrFail($token);
if ($token->created_at < new DateTime('-1 day')) {
throw new InvalidConfirmationTokenException;
}
return view('flarum::reset')->with('token', $token->id); return view('flarum::reset')->with('token', $token->id);
} }
} }

View File

@ -27,7 +27,7 @@ class LoginWithCookie implements MiddlewareInterface
public function __invoke(Request $request, Response $response, callable $out = null) public function __invoke(Request $request, Response $response, callable $out = null)
{ {
if (($token = array_get($request->getCookieParams(), 'flarum_remember')) && if (($token = array_get($request->getCookieParams(), 'flarum_remember')) &&
($accessToken = AccessToken::where('id', $token)->first()) ($accessToken = AccessToken::valid($token))
) { ) {
$this->app->instance('flarum.actor', $user = $accessToken->user); $this->app->instance('flarum.actor', $user = $accessToken->user);