use JMS\Serializer\Annotation\Accessor;
use JMS\Serializer\Annotation\Groups;
use JMS\Serializer\Annotation\XmlRoot;
+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;
* @UniqueEntity("email")
* @UniqueEntity("username")
*/
-class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorInterface
+class User extends BaseUser implements EmailTwoFactorInterface, GoogleTwoFactorInterface, BackupCodeInterface
{
use EntityTimestampsTrait;
*/
private $googleAuthenticatorSecret;
+ /**
+ * @ORM\Column(type="json_array", nullable=true)
+ */
+ private $backupCodes;
+
/**
* @var bool
*
}
/**
- * @param Entry $entry
- *
* @return User
*/
public function addEntry(Entry $entry)
$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]);
+ }
+ }
+
/**
- * @param Client $client
- *
* @return User
*/
public function addClient(Client $client)
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;
+ }
}