Remove one to one relation beetween account and token & add lastUsed field for token

This commit is contained in:
Nicolas Le Goff
2014-03-12 11:39:55 +01:00
parent 2cc2387c87
commit 63b6de5fc8
9 changed files with 67 additions and 57 deletions

View File

@@ -62,7 +62,10 @@ class V1 implements ControllerProviderInterface
}); });
$controllers->after(function (Request $request, Response $response) use ($app) { $controllers->after(function (Request $request, Response $response) use ($app) {
$app['manipulator.api-log']->create($app['session']->get('token')->getAccount(), $request, $response); $token = $app['session']->get('token');
$app['manipulator.api-log']->create($token->getAccount(), $request, $response);
$token->setLastUsed(new \DateTime());
$app['manipulator.api-oauth-token']->update($token);
$app['session']->set('token', null); $app['session']->set('token', null);
if (null !== $app['authentication']->getUser()) { if (null !== $app['authentication']->getUser()) {
$app['authentication']->closeAccount(); $app['authentication']->closeAccount();

View File

@@ -243,9 +243,11 @@ class Account implements ControllerProviderInterface
{ {
$data = []; $data = [];
foreach($app['repo.api-applications']->findByUser($app['authentication']->getUser()) as $application) { foreach ($app['repo.api-applications']->findByUser($app['authentication']->getUser()) as $application) {
$account = $app['repo.api-accounts']->findByUserAndApplication($app['authentication']->getUser(), $application);
$data[$application->getId()]['application'] = $application; $data[$application->getId()]['application'] = $application;
$data[$application->getId()]['user-account'] = $app['repo.api-accounts']->findByUserAndApplication($app['authentication']->getUser(), $application); $data[$application->getId()]['user-account'] = $account;
} }
return $app['twig']->render('account/authorized_apps.html.twig', [ return $app['twig']->render('account/authorized_apps.html.twig', [

View File

@@ -130,14 +130,14 @@ class Developers implements ControllerProviderInterface
$app->abort(404, sprintf('Account not found for application %s', $application->getName())); $app->abort(404, sprintf('Account not found for application %s', $application->getName()));
} }
$token = $account->getOauthToken(); if(null !== $devToken = $app['repo.api-oauth-tokens']->findDeveloperToken($account)) {
if ($account->hasOauthToken()) { $app['manipulator.api-oauth-token']->renew($devToken);
$app['manipulator.api-oauth-token']->renew($token);
} else { } else {
$token = $app['manipulator.api-oauth-token']->create($account); // dev tokens do not expires
$devToken = $app['manipulator.api-oauth-token']->create($account);
} }
return $app->json(['success' => true, 'token' => $token->getOauthToken()]); return $app->json(['success' => true, 'token' => $devToken->getOauthToken()]);
} }
/** /**
@@ -188,6 +188,9 @@ class Developers implements ControllerProviderInterface
sprintf('%s%s', $form->getSchemeCallback(), $form->getCallback()) sprintf('%s%s', $form->getSchemeCallback(), $form->getCallback())
); );
// create an account as well
$app['manipulator.api-account']->create($application, $app['authentication']->getUser());
return $app->redirectPath('developers_application', ['application' => $application->getId()]); return $app->redirectPath('developers_application', ['application' => $application->getId()]);
} }
@@ -241,9 +244,7 @@ class Developers implements ControllerProviderInterface
$token = null; $token = null;
if (null !== $account = $app['repo.api-accounts']->findByUserAndApplication($app['authentication']->getUser(), $application)) { if (null !== $account = $app['repo.api-accounts']->findByUserAndApplication($app['authentication']->getUser(), $application)) {
if ($account->hasOauthToken()) { $token = $app['repo.api-oauth-tokens']->findDeveloperToken($account);
$token = $account->getOauthToken()->getOauthToken();
}
} }
return $app['twig']->render('developers/application.html.twig', [ return $app['twig']->render('developers/application.html.twig', [

View File

@@ -48,14 +48,6 @@ class ApiAccount
**/ **/
private $application; private $application;
/**
* @ORM\OneToOne(targetEntity="ApiOauthToken", inversedBy="account")
* @ORM\JoinColumn(name="oauth_token", referencedColumnName="oauth_token", nullable=true)
*
* @return ApiApplication
**/
private $oauthToken;
/** /**
* @Gedmo\Timestampable(on="create") * @Gedmo\Timestampable(on="create")
* @ORM\Column(type="datetime") * @ORM\Column(type="datetime")
@@ -169,32 +161,4 @@ class ApiAccount
{ {
return $this->user; return $this->user;
} }
/**
* @param ApiOauthToken $oauthToken
*
* @return ApiAccount
*/
public function setOauthToken(ApiOauthToken $oauthToken)
{
$this->oauthToken = $oauthToken;
return $this;
}
/**
* @return ApiOauthToken
*/
public function getOauthToken()
{
return $this->oauthToken;
}
/**
* @return boolean
*/
public function hasOauthToken()
{
return null !== $this->oauthToken;
}
} }

View File

@@ -39,6 +39,12 @@ class ApiOauthToken
*/ */
private $expires; private $expires;
/**
* @Gedmo\Timestampable(on="create")
* @ORM\Column(type="datetime", name="last_used")
*/
private $lastUsed;
/** /**
* @var string * @var string
* *
@@ -197,4 +203,24 @@ class ApiOauthToken
{ {
return $this->updated; return $this->updated;
} }
/**
* @param \DateTime $lastUsed
*
* @return ApiOauthToken
*/
public function setLastUsed(\DateTime $lastUsed)
{
$this->lastUsed = $lastUsed;
return $this;
}
/**
* @return \DateTime
*/
public function getLastUsed()
{
return $this->lastUsed;
}
} }

View File

@@ -43,8 +43,6 @@ class ApiOauthTokenManipulator implements ManipulatorInterface
$token->setScope($scope); $token->setScope($scope);
$token->setAccount($account); $token->setAccount($account);
$account->setOauthToken($token);
$this->om->persist($account); $this->om->persist($account);
$this->update($token); $this->update($token);

View File

@@ -2,7 +2,9 @@
namespace Alchemy\Phrasea\Model\Repositories; namespace Alchemy\Phrasea\Model\Repositories;
use Alchemy\Phrasea\Model\Entities\ApiAccount;
use Doctrine\ORM\EntityRepository; use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query\Expr;
/** /**
* ApiOauthTokenRepository * ApiOauthTokenRepository
@@ -12,4 +14,16 @@ use Doctrine\ORM\EntityRepository;
*/ */
class ApiOauthTokenRepository extends EntityRepository class ApiOauthTokenRepository extends EntityRepository
{ {
public function findDeveloperToken(ApiAccount $account)
{
$qb = $this->createQueryBuilder('tok');
$qb->innerJoin('tok.account', 'acc', Expr\Join::WITH, $qb->expr()->eq('acc.id', ':acc_id'));
$qb->innerJoin('acc.application', 'app', Expr\Join::WITH, $qb->expr()->orx(
$qb->expr()->eq('app.creator', 'acc.user'),
$qb->expr()->isNull('app.creator')
));
$qb->setParameter(':acc_id', $account->getId());
return $qb->getQuery()->getOneOrNullResult();
}
} }

View File

@@ -217,13 +217,13 @@ class API_OAuth2_Adapter extends OAuth2
* @return $this * @return $this
* @throws RuntimeException * @throws RuntimeException
*/ */
protected function setAccessToken($oauthToken, $accountId, $expires, $scope = null) protected function setAccessToken($oauthToken, $accountId, $expires = null, $scope = null)
{ {
if (null === $account = $this->app['repo.api-accounts']->find($accountId)) { if (null === $account = $this->app['repo.api-accounts']->find($accountId)) {
throw new RuntimeException(sprintf('Account with id %s is not valid', $accountId)); throw new RuntimeException(sprintf('Account with id %s is not valid', $accountId));
} }
$expires = null === $expires ? $expires : \DateTime::createFromFormat('U', $expires);
$token = $this->app['manipulator.api-oauth-token']->create($account, null, \DateTime::createFromFormat('U', $expires), $scope); $token = $this->app['manipulator.api-oauth-token']->create($account, $expires, $scope);
$this->app['manipulator.api-oauth-token']->setOauthToken($token, $oauthToken); $this->app['manipulator.api-oauth-token']->setOauthToken($token, $oauthToken);
return $this; return $this;
@@ -764,11 +764,13 @@ class API_OAuth2_Adapter extends OAuth2
"scope" => $scope "scope" => $scope
]; ];
$expires = null;
if ($this->enable_expire) { if ($this->enable_expire) {
$token['expires_in'] = $this->getVariable('access_token_lifetime', OAUTH2_DEFAULT_ACCESS_TOKEN_LIFETIME); $token['expires_in'] = $this->getVariable('access_token_lifetime', OAUTH2_DEFAULT_ACCESS_TOKEN_LIFETIME);
$expires = time() + $this->getVariable('access_token_lifetime', OAUTH2_DEFAULT_ACCESS_TOKEN_LIFETIME);
} }
$this->setAccessToken($token["access_token"], $accountId, time() + $this->getVariable('access_token_lifetime', OAUTH2_DEFAULT_ACCESS_TOKEN_LIFETIME), $scope); $this->setAccessToken($token["access_token"], $accountId, $expires, $scope);
// Issue a refresh token also, if we support them // Issue a refresh token also, if we support them
if (in_array(OAUTH2_GRANT_TYPE_REFRESH_TOKEN, $this->getSupportedGrantTypes())) { if (in_array(OAUTH2_GRANT_TYPE_REFRESH_TOKEN, $this->getSupportedGrantTypes())) {

View File

@@ -81,18 +81,18 @@
</td> </td>
<td> <td>
<span id="my_access_token"> <span id="my_access_token">
{% if not token is none %} {% if not token is none %}
{{ token|default("") }} {{ token.getOauthToken()|default("") }}
{% else %} {% else %}
{{ "Le token n\'a pas encore ete genere" | trans }} {{ "Le token n\'a pas encore ete genere" | trans }}
{% endif %} {% endif %}
</span> </span>
<a id="generate_access" href="{{ path("submit_developers_application_token",{ "application" : application.getId()}) }}" class="btn btn-small btn-info">{{ "boutton::generer" | trans }}</a> <a id="generate_access" href="{{ path("submit_developers_application_token",{ "application" : application.getId()}) }}" class="btn btn-small btn-info">{{ "boutton::generer" | trans }}</a>
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
<div> <div class="form-actions">
<a class="btn btn-primary" href="{{ path("developers_applications") }}">{{ "boutton::retour" | trans }}</a> <a class="btn btn-primary" href="{{ path("developers_applications") }}">{{ "boutton::retour" | trans }}</a>
</div> </div>
</div> </div>