X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=src%2FWallabag%2FUserBundle%2FEntity%2FUser.php;h=43fa6a80fc2bb47b40970b936a21a2612de0a59a;hb=9f0957b831622ee577fa7d8f92ec0df6f3a8e274;hp=53c327f9b92baad663aea08adaf80f4e5f4993f5;hpb=b5d7eb148c4cd62ff187b08765f0c13c7d330fcf;p=github%2Fwallabag%2Fwallabag.git diff --git a/src/Wallabag/UserBundle/Entity/User.php b/src/Wallabag/UserBundle/Entity/User.php index 53c327f9..43fa6a80 100644 --- a/src/Wallabag/UserBundle/Entity/User.php +++ b/src/Wallabag/UserBundle/Entity/User.php @@ -8,13 +8,15 @@ use FOS\UserBundle\Model\User as BaseUser; use JMS\Serializer\Annotation\Accessor; use JMS\Serializer\Annotation\Groups; use JMS\Serializer\Annotation\XmlRoot; -use Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface; -use Scheb\TwoFactorBundle\Model\TrustedComputerInterface; +use Scheb\TwoFactorBundle\Model\BackupCodeInterface; +use Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface as EmailTwoFactorInterface; +use Scheb\TwoFactorBundle\Model\Google\TwoFactorInterface as GoogleTwoFactorInterface; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; use Symfony\Component\Security\Core\User\UserInterface; use Wallabag\ApiBundle\Entity\Client; use Wallabag\CoreBundle\Entity\Config; use Wallabag\CoreBundle\Entity\Entry; +use Wallabag\CoreBundle\Helper\EntityTimestampsTrait; /** * User. @@ -27,8 +29,10 @@ use Wallabag\CoreBundle\Entity\Entry; * @UniqueEntity("email") * @UniqueEntity("username") */ -class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterface +class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorInterface, BackupCodeInterface { + use EntityTimestampsTrait; + /** @Serializer\XmlAttribute */ /** * @var int @@ -120,16 +124,21 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf private $authCode; /** - * @var bool - * - * @ORM\Column(type="boolean") + * @ORM\Column(name="googleAuthenticatorSecret", type="string", nullable=true) */ - private $twoFactorAuthentication = false; + private $googleAuthenticatorSecret; /** * @ORM\Column(type="json_array", nullable=true) */ - private $trusted; + private $backupCodes; + + /** + * @var bool + * + * @ORM\Column(type="boolean") + */ + private $emailTwoFactor = false; public function __construct() { @@ -138,19 +147,6 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf $this->roles = ['ROLE_USER']; } - /** - * @ORM\PrePersist - * @ORM\PreUpdate - */ - public function timestamps() - { - if (null === $this->createdAt) { - $this->createdAt = new \DateTime(); - } - - $this->updatedAt = new \DateTime(); - } - /** * Set name. * @@ -243,49 +239,119 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf /** * @return bool */ - public function isTwoFactorAuthentication() + public function isEmailTwoFactor() + { + return $this->emailTwoFactor; + } + + /** + * @param bool $emailTwoFactor + */ + public function setEmailTwoFactor($emailTwoFactor) { - return $this->twoFactorAuthentication; + $this->emailTwoFactor = $emailTwoFactor; } /** - * @param bool $twoFactorAuthentication + * Used in the user config form to be "like" the email option. */ - public function setTwoFactorAuthentication($twoFactorAuthentication) + public function isGoogleTwoFactor() { - $this->twoFactorAuthentication = $twoFactorAuthentication; + return $this->isGoogleAuthenticatorEnabled(); } - public function isEmailAuthEnabled() + /** + * {@inheritdoc} + */ + public function isEmailAuthEnabled(): bool { - return $this->twoFactorAuthentication; + return $this->emailTwoFactor; } - public function getEmailAuthCode() + /** + * {@inheritdoc} + */ + public function getEmailAuthCode(): string { return $this->authCode; } - public function setEmailAuthCode($authCode) + /** + * {@inheritdoc} + */ + public function setEmailAuthCode(string $authCode): void { $this->authCode = $authCode; } - public function addTrustedComputer($token, \DateTime $validUntil) + /** + * {@inheritdoc} + */ + public function getEmailAuthRecipient(): string { - $this->trusted[$token] = $validUntil->format('r'); + return $this->email; } - public function isTrustedComputer($token) + /** + * {@inheritdoc} + */ + public function isGoogleAuthenticatorEnabled(): bool { - if (isset($this->trusted[$token])) { - $now = new \DateTime(); - $validUntil = new \DateTime($this->trusted[$token]); + return $this->googleAuthenticatorSecret ? true : false; + } - return $now < $validUntil; - } + /** + * {@inheritdoc} + */ + public function getGoogleAuthenticatorUsername(): string + { + return $this->username; + } - return false; + /** + * {@inheritdoc} + */ + public function getGoogleAuthenticatorSecret(): string + { + return $this->googleAuthenticatorSecret; + } + + /** + * {@inheritdoc} + */ + public function setGoogleAuthenticatorSecret(?string $googleAuthenticatorSecret): void + { + $this->googleAuthenticatorSecret = $googleAuthenticatorSecret; + } + + public function setBackupCodes(array $codes = null) + { + $this->backupCodes = $codes; + } + + public function getBackupCodes() + { + return $this->backupCodes; + } + + /** + * {@inheritdoc} + */ + public function isBackupCode(string $code): bool + { + return false === $this->findBackupCode($code) ? false : true; + } + + /** + * {@inheritdoc} + */ + public function invalidateBackupCode(string $code): void + { + $key = $this->findBackupCode($code); + + if (false !== $key) { + unset($this->backupCodes[$key]); + } } /** @@ -319,4 +385,24 @@ class User extends BaseUser implements TwoFactorInterface, TrustedComputerInterf return $this->clients->first(); } } + + /** + * Try to find a backup code from the list of backup codes of the current user. + * + * @param string $code Given code from the user + * + * @return string|false + */ + private function findBackupCode(string $code) + { + foreach ($this->backupCodes as $key => $backupCode) { + // backup code are hashed using `password_hash` + // see ConfigController->otpAppAction + if (password_verify($code, $backupCode)) { + return $key; + } + } + + return false; + } }