mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-15 14:03:27 +00:00
Merge pull request #1760 from bburnichon/improvement/some-scrutinizers-fixups
Improvement/some scrutinizers fixups
This commit is contained in:
@@ -14,7 +14,6 @@ use Alchemy\Phrasea\Model\Entities\User;
|
|||||||
|
|
||||||
trait AclAware
|
trait AclAware
|
||||||
{
|
{
|
||||||
/** @var ACLProvider */
|
|
||||||
private $aclProvider;
|
private $aclProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -45,17 +44,20 @@ trait AclAware
|
|||||||
return $this->aclProvider;
|
return $this->aclProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null === $this->aclProvider && $this instanceof \Pimple && $this->offsetExists('acl')) {
|
$locator = $this->aclProvider;
|
||||||
$this->aclProvider = function () {
|
|
||||||
|
if (null === $locator && $this instanceof \Pimple && $this->offsetExists('acl')) {
|
||||||
|
$locator = function () {
|
||||||
return $this['acl'];
|
return $this['acl'];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null === $this->aclProvider) {
|
if (null === $locator) {
|
||||||
throw new \LogicException(ACLProvider::class . ' instance or locator was not set');
|
throw new \LogicException(ACLProvider::class . ' instance or locator was not set');
|
||||||
}
|
}
|
||||||
|
|
||||||
$instance = call_user_func($this->aclProvider);
|
$instance = $locator();
|
||||||
|
|
||||||
if (!$instance instanceof ACLProvider) {
|
if (!$instance instanceof ACLProvider) {
|
||||||
throw new \LogicException(sprintf(
|
throw new \LogicException(sprintf(
|
||||||
'Expects locator to return instance of "%s", got "%s"',
|
'Expects locator to return instance of "%s", got "%s"',
|
||||||
|
@@ -13,24 +13,35 @@ namespace Alchemy\Phrasea\Authentication\Phrasea;
|
|||||||
|
|
||||||
use Alchemy\Phrasea\Exception\InvalidArgumentException;
|
use Alchemy\Phrasea\Exception\InvalidArgumentException;
|
||||||
use Alchemy\Phrasea\Authentication\Exception\RequireCaptchaException;
|
use Alchemy\Phrasea\Authentication\Exception\RequireCaptchaException;
|
||||||
|
use Alchemy\Phrasea\Model\Repositories\AuthFailureRepository;
|
||||||
use Doctrine\ORM\EntityManager;
|
use Doctrine\ORM\EntityManager;
|
||||||
use Alchemy\Phrasea\Model\Entities\AuthFailure;
|
use Alchemy\Phrasea\Model\Entities\AuthFailure;
|
||||||
use Doctrine\ORM\EntityRepository;
|
|
||||||
use Neutron\ReCaptcha\ReCaptcha;
|
use Neutron\ReCaptcha\ReCaptcha;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
class FailureManager
|
class FailureManager
|
||||||
{
|
{
|
||||||
/** @var ReCaptcha */
|
/**
|
||||||
|
* @var ReCaptcha
|
||||||
|
*/
|
||||||
private $captcha;
|
private $captcha;
|
||||||
/** @var EntityManager */
|
|
||||||
|
/**
|
||||||
|
* @var EntityManager
|
||||||
|
*/
|
||||||
private $em;
|
private $em;
|
||||||
/** @var EntityRepository */
|
|
||||||
|
/**
|
||||||
|
* @var AuthFailureRepository
|
||||||
|
*/
|
||||||
private $repository;
|
private $repository;
|
||||||
/** @var integer */
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
private $trials;
|
private $trials;
|
||||||
|
|
||||||
public function __construct(EntityRepository $repo, EntityManager $em, ReCaptcha $captcha, $trials)
|
public function __construct(AuthFailureRepository $repo, EntityManager $em, ReCaptcha $captcha, $trials)
|
||||||
{
|
{
|
||||||
$this->captcha = $captcha;
|
$this->captcha = $captcha;
|
||||||
$this->em = $em;
|
$this->em = $em;
|
||||||
@@ -40,9 +51,12 @@ class FailureManager
|
|||||||
throw new InvalidArgumentException('Trials number must be a positive integer');
|
throw new InvalidArgumentException('Trials number must be a positive integer');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->trials = $trials;
|
$this->trials = (int)$trials;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
public function getTrials()
|
public function getTrials()
|
||||||
{
|
{
|
||||||
return $this->trials;
|
return $this->trials;
|
||||||
@@ -86,36 +100,38 @@ class FailureManager
|
|||||||
$failures = $this->repository->findLockedFailuresMatching($username, $request->getClientIp());
|
$failures = $this->repository->findLockedFailuresMatching($username, $request->getClientIp());
|
||||||
|
|
||||||
if (0 === count($failures)) {
|
if (0 === count($failures)) {
|
||||||
return;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->trials < count($failures) && $this->captcha->isSetup()) {
|
if ($this->trials < count($failures) && $this->captcha->isSetup()) {
|
||||||
$response = $this->captcha->bind($request);
|
$response = $this->captcha->bind($request);
|
||||||
|
|
||||||
if ($response->isValid()) {
|
if (!$response->isValid()) {
|
||||||
foreach ($failures as $failure) {
|
throw new RequireCaptchaException('Too many failures, require captcha');
|
||||||
$failure->setLocked(false);
|
|
||||||
}
|
|
||||||
$this->em->flush();
|
|
||||||
} else {
|
|
||||||
throw new RequireCaptchaException('Too much failure, require captcha');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach ($failures as $failure) {
|
||||||
|
$failure->setLocked(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->em->flush($failures);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes failures older than 2 monthes
|
|
||||||
*/
|
|
||||||
private function removeOldFailures()
|
private function removeOldFailures()
|
||||||
{
|
{
|
||||||
$failures = $this->repository->findOldFailures('-2 months');
|
$failures = $this->repository->findOldFailures('-2 months');
|
||||||
|
|
||||||
if (0 < count($failures)) {
|
if (empty($failures)) {
|
||||||
foreach ($failures as $failure) {
|
return;
|
||||||
$this->em->remove($failure);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach ($failures as $failure) {
|
||||||
|
$this->em->remove($failure);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->em->flush($failures);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -15,13 +15,13 @@ use Alchemy\Phrasea\Authentication\Exception\NotAuthenticatedException;
|
|||||||
use Alchemy\Phrasea\Authentication\Provider\Token\Token;
|
use Alchemy\Phrasea\Authentication\Provider\Token\Token;
|
||||||
use Alchemy\Phrasea\Authentication\Provider\Token\Identity;
|
use Alchemy\Phrasea\Authentication\Provider\Token\Identity;
|
||||||
use Alchemy\Phrasea\Model\Entities\User;
|
use Alchemy\Phrasea\Model\Entities\User;
|
||||||
use Doctrine\Common\Persistence\ObjectRepository;
|
use Alchemy\Phrasea\Model\Repositories\UserRepository;
|
||||||
|
|
||||||
class SuggestionFinder
|
class SuggestionFinder
|
||||||
{
|
{
|
||||||
private $repository;
|
private $repository;
|
||||||
|
|
||||||
public function __construct(ObjectRepository $repository)
|
public function __construct(UserRepository $repository)
|
||||||
{
|
{
|
||||||
$this->repository = $repository;
|
$this->repository = $repository;
|
||||||
}
|
}
|
||||||
|
@@ -33,19 +33,16 @@ class Factory
|
|||||||
*/
|
*/
|
||||||
public static function getFileAttribute(Application $app, $name, $serialized)
|
public static function getFileAttribute(Application $app, $name, $serialized)
|
||||||
{
|
{
|
||||||
switch ($name) {
|
switch ($name)
|
||||||
|
{
|
||||||
case AttributeInterface::NAME_METADATA:
|
case AttributeInterface::NAME_METADATA:
|
||||||
return Metadata::loadFromString($app, $serialized);
|
return Metadata::loadFromString($app, $serialized);
|
||||||
break;
|
|
||||||
case AttributeInterface::NAME_STORY:
|
case AttributeInterface::NAME_STORY:
|
||||||
return Story::loadFromString($app, $serialized);
|
return Story::loadFromString($app, $serialized);
|
||||||
break;
|
|
||||||
case AttributeInterface::NAME_METAFIELD:
|
case AttributeInterface::NAME_METAFIELD:
|
||||||
return MetaField::loadFromString($app, $serialized);
|
return MetaField::loadFromString($app, $serialized);
|
||||||
break;
|
|
||||||
case AttributeInterface::NAME_STATUS:
|
case AttributeInterface::NAME_STATUS:
|
||||||
return Status::loadFromString($app, $serialized);
|
return Status::loadFromString($app, $serialized);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new \InvalidArgumentException(sprintf('Unknown attribute %s', $name));
|
throw new \InvalidArgumentException(sprintf('Unknown attribute %s', $name));
|
||||||
|
@@ -12,7 +12,6 @@
|
|||||||
namespace Alchemy\Phrasea\Border\Attribute;
|
namespace Alchemy\Phrasea\Border\Attribute;
|
||||||
|
|
||||||
use Alchemy\Phrasea\Application;
|
use Alchemy\Phrasea\Application;
|
||||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Phraseanet Border MetaField Attribute
|
* Phraseanet Border MetaField Attribute
|
||||||
@@ -23,13 +22,11 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
|||||||
class MetaField implements AttributeInterface
|
class MetaField implements AttributeInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @var \databox_field
|
* @var \databox_field
|
||||||
*/
|
*/
|
||||||
protected $databox_field;
|
protected $databox_field;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $value;
|
protected $value;
|
||||||
@@ -46,14 +43,6 @@ class MetaField implements AttributeInterface
|
|||||||
$this->value = $value;
|
$this->value = $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Destructor
|
|
||||||
*/
|
|
||||||
public function __destruct()
|
|
||||||
{
|
|
||||||
$this->metadata = $this->databox_field = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
@@ -101,15 +90,18 @@ class MetaField implements AttributeInterface
|
|||||||
*/
|
*/
|
||||||
public static function loadFromString(Application $app, $string)
|
public static function loadFromString(Application $app, $string)
|
||||||
{
|
{
|
||||||
if (!$datas = @unserialize($string)) {
|
$data = @unserialize($string);
|
||||||
|
|
||||||
|
if (!is_array($data) || !isset($data['sbas_id']) || !isset($data['id']) || !isset($data['value'])) {
|
||||||
throw new \InvalidArgumentException('Unable to load metadata from string');
|
throw new \InvalidArgumentException('Unable to load metadata from string');
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return new static($app->findDataboxById($datas['sbas_id'])
|
$field = $app->findDataboxById($data['sbas_id'])->get_meta_structure()->get_element($data['id']);
|
||||||
->get_meta_structure()->get_element($datas['id']), $datas['value']);
|
|
||||||
} catch (NotFoundHttpException $e) {
|
return new static($field, $data['value']);
|
||||||
throw new \InvalidArgumentException('Field does not exist anymore');
|
} catch (\Exception $exception) {
|
||||||
|
throw new \InvalidArgumentException('Field does not exist anymore', 0, $exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -129,8 +129,6 @@ class Manager
|
|||||||
$callable($element, $visa, $code);
|
$callable($element, $visa, $code);
|
||||||
}
|
}
|
||||||
|
|
||||||
$visa = null;
|
|
||||||
|
|
||||||
return $code;
|
return $code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -45,8 +45,6 @@ class CLI extends Application
|
|||||||
{
|
{
|
||||||
parent::__construct($environment);
|
parent::__construct($environment);
|
||||||
|
|
||||||
$app = $this;
|
|
||||||
|
|
||||||
$this['session.test'] = true;
|
$this['session.test'] = true;
|
||||||
|
|
||||||
$this['console'] = $this->share(function () use ($name, $version) {
|
$this['console'] = $this->share(function () use ($name, $version) {
|
||||||
|
@@ -92,7 +92,7 @@ EOT;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $collectionId
|
* @param int $collectionId
|
||||||
*/
|
*/
|
||||||
public function setCollectionId($collectionId)
|
public function setCollectionId($collectionId)
|
||||||
{
|
{
|
||||||
@@ -126,7 +126,7 @@ EOT;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return \string[]
|
* @return string[]
|
||||||
*/
|
*/
|
||||||
public function getLabels()
|
public function getLabels()
|
||||||
{
|
{
|
||||||
@@ -134,7 +134,7 @@ EOT;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \string[] $labels
|
* @param string[] $labels
|
||||||
*/
|
*/
|
||||||
public function setLabels($labels)
|
public function setLabels($labels)
|
||||||
{
|
{
|
||||||
@@ -142,7 +142,7 @@ EOT;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $lang
|
* @param string $lang
|
||||||
* @param bool $substitute
|
* @param bool $substitute
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
@@ -154,14 +154,14 @@ EOT;
|
|||||||
|
|
||||||
if ($substitute) {
|
if ($substitute) {
|
||||||
return isset($this->labels[$lang]) ? $this->labels[$lang] : $this->name;
|
return isset($this->labels[$lang]) ? $this->labels[$lang] : $this->name;
|
||||||
} else {
|
|
||||||
return $this->labels[$lang];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return $this->labels[$lang];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $lang
|
* @param string $lang
|
||||||
* @param $label
|
* @param string $label
|
||||||
*/
|
*/
|
||||||
public function setLabel($lang, $label)
|
public function setLabel($lang, $label)
|
||||||
{
|
{
|
||||||
@@ -173,7 +173,7 @@ EOT;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return \int[]|string|null
|
* @return int[]|string|null
|
||||||
*/
|
*/
|
||||||
public function getLogo()
|
public function getLogo()
|
||||||
{
|
{
|
||||||
@@ -181,7 +181,7 @@ EOT;
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \int[]|string $logo
|
* @param int[]|string $logo
|
||||||
*/
|
*/
|
||||||
public function setLogo($logo)
|
public function setLogo($logo)
|
||||||
{
|
{
|
||||||
|
@@ -13,7 +13,7 @@ class ArrayCacheCollectionRepository implements CollectionRepository
|
|||||||
private $collectionRepository;
|
private $collectionRepository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var \collection[]
|
* @var \collection[]|null
|
||||||
*/
|
*/
|
||||||
private $collectionCache = null;
|
private $collectionCache = null;
|
||||||
|
|
||||||
|
@@ -18,16 +18,13 @@ use Symfony\Component\Console\Output\OutputInterface;
|
|||||||
|
|
||||||
class BuildMissingSubdefs extends Command
|
class BuildMissingSubdefs extends Command
|
||||||
{
|
{
|
||||||
/**
|
private $generator;
|
||||||
* Constructor
|
|
||||||
*/
|
|
||||||
public function __construct($name = null)
|
public function __construct($name = null)
|
||||||
{
|
{
|
||||||
parent::__construct($name);
|
parent::__construct($name);
|
||||||
|
|
||||||
$this->setDescription('Builds subviews that previously failed to be generated / did not exist when records were added');
|
$this->setDescription('Builds subviews that previously failed to be generated / did not exist when records were added');
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -37,48 +34,61 @@ class BuildMissingSubdefs extends Command
|
|||||||
{
|
{
|
||||||
$start = microtime(true);
|
$start = microtime(true);
|
||||||
$progressBar = new ProgressBar($output);
|
$progressBar = new ProgressBar($output);
|
||||||
$n = 0;
|
$generatedSubdefs = 0;
|
||||||
|
|
||||||
/** @var SubdefGenerator $subdefGenerator */
|
|
||||||
$subdefGenerator = $this->container['subdef.generator'];
|
|
||||||
|
|
||||||
foreach ($this->container->getDataboxes() as $databox) {
|
foreach ($this->container->getDataboxes() as $databox) {
|
||||||
$sql = 'SELECT record_id FROM record WHERE parent_record_id = 0';
|
$sql = 'SELECT record_id FROM record WHERE parent_record_id = 0';
|
||||||
$stmt = $databox->get_connection()->prepare($sql);
|
$result = $databox->get_connection()->executeQuery($sql)->fetchAll(\PDO::FETCH_ASSOC);
|
||||||
$stmt->execute();
|
$progressBar->start(count($result));
|
||||||
$rs = $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
|
||||||
$stmt->closeCursor();
|
|
||||||
$progressBar->start(count($rs));
|
|
||||||
|
|
||||||
foreach ($rs as $row) {
|
foreach ($result as $row) {
|
||||||
$record = $databox->get_record($row['record_id']);
|
$record = $databox->get_record($row['record_id']);
|
||||||
|
|
||||||
$wanted_subdefs = $record->get_missing_subdefs();
|
$generatedSubdefs += $this->generateRecordMissingSubdefs($record);
|
||||||
|
|
||||||
if (count($wanted_subdefs) > 0) {
|
|
||||||
$subdefGenerator->generateSubdefs($record, $wanted_subdefs);
|
|
||||||
|
|
||||||
foreach ($wanted_subdefs as $subdef) {
|
|
||||||
$this->container['monolog']->addInfo("generate " . $subdef . " for record " . $record->get_record_id());
|
|
||||||
$n++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unset($record);
|
|
||||||
$progressBar->advance();
|
$progressBar->advance();
|
||||||
}
|
}
|
||||||
|
|
||||||
$progressBar->finish();
|
$progressBar->finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->container['monolog']->addInfo($n . " subdefs done");
|
$this->container['monolog']->addInfo($generatedSubdefs . " subdefs done");
|
||||||
$stop = microtime(true);
|
$stop = microtime(true);
|
||||||
$duration = $stop - $start;
|
$duration = $stop - $start;
|
||||||
|
|
||||||
$this->container['monolog']->addInfo(sprintf("process took %s, (%f sd/s.)", $this->getFormattedDuration($duration), round($n / $duration, 3)));
|
$this->container['monolog']->addInfo(sprintf("process took %s, (%f sd/s.)", $this->getFormattedDuration($duration), round($generatedSubdefs / $duration, 3)));
|
||||||
$progressBar->finish();
|
$progressBar->finish();
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate subdef generation and return number of subdef
|
||||||
|
* @param \record_adapter $record
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
protected function generateRecordMissingSubdefs(\record_adapter $record)
|
||||||
|
{
|
||||||
|
$wanted_subdefs = $record->get_missing_subdefs();
|
||||||
|
|
||||||
|
if (!empty($wanted_subdefs)) {
|
||||||
|
$this->getSubdefGenerator()->generateSubdefs($record, $wanted_subdefs);
|
||||||
|
|
||||||
|
foreach ($wanted_subdefs as $subdef) {
|
||||||
|
$this->container['monolog']->addInfo("generate " . $subdef . " for record " . $record->getRecordId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count($wanted_subdefs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return SubdefGenerator
|
||||||
|
*/
|
||||||
|
protected function getSubdefGenerator()
|
||||||
|
{
|
||||||
|
if (null === $this->generator) {
|
||||||
|
$this->generator = $this->container['subdef.generator'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->generator;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
/*
|
|
||||||
* This file is part of Phraseanet
|
* This file is part of Phraseanet
|
||||||
*
|
*
|
||||||
* (c) 2005-2014 Alchemy
|
* (c) 2005-2016 Alchemy
|
||||||
*
|
*
|
||||||
* For the full copyright and license information, please view the LICENSE
|
* For the full copyright and license information, please view the LICENSE
|
||||||
* file that was distributed with this source code.
|
* file that was distributed with this source code.
|
||||||
@@ -14,19 +13,15 @@ namespace Alchemy\Phrasea\Command;
|
|||||||
use Alchemy\Phrasea\Exception\InvalidArgumentException;
|
use Alchemy\Phrasea\Exception\InvalidArgumentException;
|
||||||
use Alchemy\Phrasea\Media\SubdefGenerator;
|
use Alchemy\Phrasea\Media\SubdefGenerator;
|
||||||
use Doctrine\DBAL\Connection;
|
use Doctrine\DBAL\Connection;
|
||||||
use Doctrine\DBAL\SQLParserUtils;
|
|
||||||
use Symfony\Component\Console\Input\InputArgument;
|
use Symfony\Component\Console\Input\InputArgument;
|
||||||
use Symfony\Component\Console\Input\InputOption;
|
use Symfony\Component\Console\Input\InputOption;
|
||||||
use Symfony\Component\Console\Input\InputInterface;
|
use Symfony\Component\Console\Input\InputInterface;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
use Symfony\Component\Console\Helper\HelperSet;
|
|
||||||
use Symfony\Component\Console\Helper\ProgressBar;
|
use Symfony\Component\Console\Helper\ProgressBar;
|
||||||
use media_subdef;
|
use media_subdef;
|
||||||
|
|
||||||
class BuildSubdefs extends Command
|
class BuildSubdefs extends Command
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*/
|
|
||||||
public function __construct($name = null)
|
public function __construct($name = null)
|
||||||
{
|
{
|
||||||
parent::__construct($name);
|
parent::__construct($name);
|
||||||
@@ -39,8 +34,6 @@ class BuildSubdefs extends Command
|
|||||||
$this->addOption('min_record', 'min', InputOption::VALUE_OPTIONAL, 'Min record id');
|
$this->addOption('min_record', 'min', InputOption::VALUE_OPTIONAL, 'Min record id');
|
||||||
$this->addOption('with-substitution', 'wsubstit', InputOption::VALUE_NONE, 'Regenerate subdefs for substituted records as well');
|
$this->addOption('with-substitution', 'wsubstit', InputOption::VALUE_NONE, 'Regenerate subdefs for substituted records as well');
|
||||||
$this->addOption('substitution-only', 'substito', InputOption::VALUE_NONE, 'Regenerate subdefs for substituted records only');
|
$this->addOption('substitution-only', 'substito', InputOption::VALUE_NONE, 'Regenerate subdefs for substituted records only');
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -70,111 +63,46 @@ class BuildSubdefs extends Command
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$sqlCount = "SELECT COUNT(DISTINCT(r.record_id)) AS nb_records"
|
$min = $input->getOption('min_record');
|
||||||
. " FROM record r LEFT JOIN subdef s ON (r.record_id = s.record_id AND s.name IN (?))"
|
$max = $input->getOption('max_record');
|
||||||
. " WHERE r.type IN (?)";
|
|
||||||
|
|
||||||
$types = array(Connection::PARAM_STR_ARRAY, Connection::PARAM_STR_ARRAY);
|
|
||||||
$params = array($subdefsName, $recordsType);
|
|
||||||
|
|
||||||
if (null !== $min = $input->getOption('min_record')) {
|
|
||||||
$sqlCount .= " AND (r.record_id >= ?)";
|
|
||||||
|
|
||||||
$params[] = (int) $min;
|
|
||||||
$types[] = \PDO::PARAM_INT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (null !== $max = $input->getOption('max_record')) {
|
|
||||||
$sqlCount .= " AND (r.record_id <= ?)";
|
|
||||||
|
|
||||||
$params[] = (int) $max;
|
|
||||||
$types[] = \PDO::PARAM_INT;
|
|
||||||
}
|
|
||||||
|
|
||||||
$substitutionOnly = $input->getOption('substitution-only');
|
$substitutionOnly = $input->getOption('substitution-only');
|
||||||
$withSubstitution = $input->getOption('with-substitution');
|
$withSubstitution = $input->getOption('with-substitution');
|
||||||
|
|
||||||
if (false === $withSubstitution) {
|
if (false !== $withSubstitution && false !== $substitutionOnly) {
|
||||||
if (true === $substitutionOnly) {
|
|
||||||
$sqlCount .= " AND (ISNULL(s.substit) OR s.substit = 1)";
|
|
||||||
} else {
|
|
||||||
$sqlCount .= " AND (ISNULL(s.substit) OR s.substit = 0)";
|
|
||||||
}
|
|
||||||
} elseif ($substitutionOnly) {
|
|
||||||
throw new InvalidArgumentException('Conflict, you can not ask for --substitution-only && --with-substitution parameters at the same time');
|
throw new InvalidArgumentException('Conflict, you can not ask for --substitution-only && --with-substitution parameters at the same time');
|
||||||
}
|
}
|
||||||
|
|
||||||
list($sqlCount, $stmtParams) = SQLParserUtils::expandListParameters($sqlCount, $params, $types);
|
list($sql, $params, $types) = $this->generateSQL($subdefsName, $recordsType, $min, $max, $withSubstitution, $substitutionOnly);
|
||||||
|
|
||||||
$databox = $this->container->findDataboxById($input->getArgument('databox'));
|
$databox = $this->container->findDataboxById($input->getArgument('databox'));
|
||||||
|
|
||||||
$output->writeln($sqlCount);
|
|
||||||
|
|
||||||
$connection = $databox->get_connection();
|
$connection = $databox->get_connection();
|
||||||
$stmt = $connection->prepare($sqlCount);
|
|
||||||
$stmt->execute($stmtParams);
|
$sqlCount = sprintf('SELECT COUNT(*) FROM (%s)', $sql);
|
||||||
$row = $stmt->fetch();
|
$output->writeln($sqlCount);
|
||||||
$totalRecords = $row['nb_records'];
|
$totalRecords = (int)$connection->executeQuery($sqlCount, $params, $types)->fetchColumn();
|
||||||
|
|
||||||
if ($totalRecords === 0) {
|
if ($totalRecords === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var HelperSet $helperSet */
|
$progress = new ProgressBar($output, $totalRecords);
|
||||||
$helperSet = $this->getHelperSet();
|
|
||||||
|
|
||||||
/** @var ProgressBar $progress */
|
$progress->start();
|
||||||
$progress = $helperSet->get('progress');
|
|
||||||
|
|
||||||
$progress->start($output, $totalRecords);
|
|
||||||
|
|
||||||
$progress->display();
|
$progress->display();
|
||||||
|
|
||||||
$sql = "SELECT DISTINCT(r.record_id)"
|
$rows = $connection->executeQuery($sql, $params, $types)->fetchAll(\PDO::FETCH_ASSOC);
|
||||||
. " FROM record r LEFT JOIN subdef s ON (r.record_id = s.record_id AND s.name IN (?))"
|
|
||||||
. " WHERE r.type IN (?)";
|
|
||||||
|
|
||||||
$types = array(Connection::PARAM_STR_ARRAY, Connection::PARAM_STR_ARRAY);
|
|
||||||
$params = array($subdefsName, $recordsType);
|
|
||||||
|
|
||||||
if ($min) {
|
|
||||||
$sql .= " AND (r.record_id >= ?)";
|
|
||||||
|
|
||||||
$params[] = (int) $min;
|
|
||||||
$types[] = \PDO::PARAM_INT;
|
|
||||||
}
|
|
||||||
if ($max) {
|
|
||||||
$sql .= " AND (r.record_id <= ?)";
|
|
||||||
|
|
||||||
$params[] = (int) $max;
|
|
||||||
$types[] = \PDO::PARAM_INT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (false === $withSubstitution) {
|
|
||||||
if (true === $substitutionOnly) {
|
|
||||||
$sql .= " AND (ISNULL(s.substit) OR s.substit = 1)";
|
|
||||||
} else {
|
|
||||||
$sql .= " AND (ISNULL(s.substit) OR s.substit = 0)";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
list($sql, $stmtParams) = SQLParserUtils::expandListParameters($sql, $params, $types);
|
|
||||||
|
|
||||||
$connection = $databox->get_connection();
|
|
||||||
$stmt = $connection->prepare($sql);
|
|
||||||
$stmt->execute($stmtParams);
|
|
||||||
$rows = $stmt->fetchAll(\PDO::FETCH_ASSOC);
|
|
||||||
|
|
||||||
foreach ($rows as $row) {
|
foreach ($rows as $row) {
|
||||||
$output->write(sprintf(' (#%s)', $row['record_id']));
|
$output->write(sprintf(' (#%s)', $row['record_id']));
|
||||||
|
|
||||||
$record = new \record_adapter($this->container, $databox->get_sbas_id(), $row['record_id']);
|
$record = $databox->get_record($row['record_id']);
|
||||||
|
|
||||||
/** @var media_subdef[] $subdefs */
|
|
||||||
$subdefs = array_filter($record->get_subdefs(), function(media_subdef $subdef) use ($subdefsName) {
|
$subdefs = array_filter($record->get_subdefs(), function(media_subdef $subdef) use ($subdefsName) {
|
||||||
return in_array($subdef->get_name(), $subdefsName);
|
return in_array($subdef->get_name(), $subdefsName);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/** @var media_subdef $subdef */
|
||||||
foreach ($subdefs as $subdef) {
|
foreach ($subdefs as $subdef) {
|
||||||
$subdef->remove_file();
|
$subdef->remove_file();
|
||||||
if (($withSubstitution && $subdef->is_substituted()) || $substitutionOnly) {
|
if (($withSubstitution && $subdef->is_substituted()) || $substitutionOnly) {
|
||||||
@@ -186,13 +114,49 @@ class BuildSubdefs extends Command
|
|||||||
$subdefGenerator = $this->container['subdef.generator'];
|
$subdefGenerator = $this->container['subdef.generator'];
|
||||||
$subdefGenerator->generateSubdefs($record, $subdefsName);
|
$subdefGenerator->generateSubdefs($record, $subdefsName);
|
||||||
|
|
||||||
$stmt->closeCursor();
|
|
||||||
|
|
||||||
$progress->advance();
|
$progress->advance();
|
||||||
}
|
}
|
||||||
|
|
||||||
unset($rows, $record, $stmt, $connection);
|
|
||||||
|
|
||||||
$progress->finish();
|
$progress->finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string[] $subdefNames
|
||||||
|
* @param string[] $recordTypes
|
||||||
|
* @param null|int $min
|
||||||
|
* @param null|int $max
|
||||||
|
* @param bool $withSubstitution
|
||||||
|
* @param bool $substitutionOnly
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
protected function generateSQL(array $subdefNames, array $recordTypes, $min, $max, $withSubstitution, $substitutionOnly)
|
||||||
|
{
|
||||||
|
$sql = "SELECT DISTINCT(r.record_id) AS record_id"
|
||||||
|
. " FROM record r LEFT JOIN subdef s ON (r.record_id = s.record_id AND s.name IN (?))"
|
||||||
|
. " WHERE r.type IN (?)";
|
||||||
|
|
||||||
|
$types = array(Connection::PARAM_STR_ARRAY, Connection::PARAM_STR_ARRAY);
|
||||||
|
$params = array($subdefNames, $recordTypes);
|
||||||
|
|
||||||
|
if (null !== $min) {
|
||||||
|
$sql .= " AND (r.record_id >= ?)";
|
||||||
|
|
||||||
|
$params[] = (int)$min;
|
||||||
|
$types[] = \PDO::PARAM_INT;
|
||||||
|
}
|
||||||
|
if (null !== $max) {
|
||||||
|
$sql .= " AND (r.record_id <= ?)";
|
||||||
|
|
||||||
|
$params[] = (int)$max;
|
||||||
|
$types[] = \PDO::PARAM_INT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (false === $withSubstitution) {
|
||||||
|
$sql .= " AND (ISNULL(s.substit) OR s.substit = ?)";
|
||||||
|
$params[] = $substitutionOnly ? 1 : 0;
|
||||||
|
$types[] = \PDO::PARAM_INT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return array($sql, $params, $types);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
/*
|
|
||||||
* This file is part of Phraseanet
|
* This file is part of Phraseanet
|
||||||
*
|
*
|
||||||
* (c) 2005-2014 Alchemy
|
* (c) 2005-2016 Alchemy
|
||||||
*
|
*
|
||||||
* For the full copyright and license information, please view the LICENSE
|
* For the full copyright and license information, please view the LICENSE
|
||||||
* file that was distributed with this source code.
|
* file that was distributed with this source code.
|
||||||
@@ -11,16 +10,15 @@
|
|||||||
|
|
||||||
namespace Alchemy\Phrasea\Model\Repositories;
|
namespace Alchemy\Phrasea\Model\Repositories;
|
||||||
|
|
||||||
|
use Alchemy\Phrasea\Model\Entities\AuthFailure;
|
||||||
use Doctrine\ORM\EntityRepository;
|
use Doctrine\ORM\EntityRepository;
|
||||||
|
|
||||||
/**
|
|
||||||
* AuthFailureRepository
|
|
||||||
*
|
|
||||||
* This class was generated by the Doctrine ORM. Add your own custom
|
|
||||||
* repository methods below.
|
|
||||||
*/
|
|
||||||
class AuthFailureRepository extends EntityRepository
|
class AuthFailureRepository extends EntityRepository
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @param string $limit
|
||||||
|
* @return AuthFailure[]
|
||||||
|
*/
|
||||||
public function findOldFailures($limit = '-2 months')
|
public function findOldFailures($limit = '-2 months')
|
||||||
{
|
{
|
||||||
$date = new \DateTime($limit);
|
$date = new \DateTime($limit);
|
||||||
@@ -37,6 +35,11 @@ class AuthFailureRepository extends EntityRepository
|
|||||||
return $query->getResult();
|
return $query->getResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $username
|
||||||
|
* @param string $ip
|
||||||
|
* @return AuthFailure[]
|
||||||
|
*/
|
||||||
public function findLockedFailuresMatching($username, $ip)
|
public function findLockedFailuresMatching($username, $ip)
|
||||||
{
|
{
|
||||||
$dql = 'SELECT f
|
$dql = 'SELECT f
|
||||||
@@ -46,7 +49,7 @@ class AuthFailureRepository extends EntityRepository
|
|||||||
|
|
||||||
$params = [
|
$params = [
|
||||||
'username' => $username,
|
'username' => $username,
|
||||||
'ip' => $ip,
|
'ip' => $ip,
|
||||||
];
|
];
|
||||||
|
|
||||||
$query = $this->_em->createQuery($dql);
|
$query = $this->_em->createQuery($dql);
|
||||||
|
@@ -4,6 +4,7 @@ namespace Alchemy\Tests\Phrasea\Authentication\Phrasea;
|
|||||||
|
|
||||||
use Alchemy\Phrasea\Authentication\Phrasea\FailureManager;
|
use Alchemy\Phrasea\Authentication\Phrasea\FailureManager;
|
||||||
use Alchemy\Phrasea\Model\Entities\AuthFailure;
|
use Alchemy\Phrasea\Model\Entities\AuthFailure;
|
||||||
|
use Alchemy\Phrasea\Model\Repositories\AuthFailureRepository;
|
||||||
use Gedmo\Timestampable\TimestampableListener;
|
use Gedmo\Timestampable\TimestampableListener;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
@@ -18,7 +19,7 @@ class FailureManagerTest extends \PhraseanetTestCase
|
|||||||
*/
|
*/
|
||||||
public function testSaveFailure()
|
public function testSaveFailure()
|
||||||
{
|
{
|
||||||
$repo = $this->getRepo();
|
$repo = $this->createAuthFailureRepositoryMock();
|
||||||
$em = $this->createEntityManagerMock();
|
$em = $this->createEntityManagerMock();
|
||||||
$recaptcha = $this->getReCaptchaMock(null);
|
$recaptcha = $this->getReCaptchaMock(null);
|
||||||
|
|
||||||
@@ -31,8 +32,8 @@ class FailureManagerTest extends \PhraseanetTestCase
|
|||||||
->will($this->returnValue($ip));
|
->will($this->returnValue($ip));
|
||||||
|
|
||||||
$oldFailures = [
|
$oldFailures = [
|
||||||
$this->getMock('Alchemy\Phrasea\Model\Entities\AuthFailure'),
|
$this->getMock(AuthFailure::class),
|
||||||
$this->getMock('Alchemy\Phrasea\Model\Entities\AuthFailure')
|
$this->getMock(AuthFailure::class)
|
||||||
];
|
];
|
||||||
|
|
||||||
$repo->expects($this->once())
|
$repo->expects($this->once())
|
||||||
@@ -41,12 +42,12 @@ class FailureManagerTest extends \PhraseanetTestCase
|
|||||||
|
|
||||||
$em->expects($this->exactly(count($oldFailures)))
|
$em->expects($this->exactly(count($oldFailures)))
|
||||||
->method('remove')
|
->method('remove')
|
||||||
->with($this->isInstanceOf('Alchemy\Phrasea\Model\Entities\AuthFailure'));
|
->with($this->isInstanceOf(AuthFailure::class));
|
||||||
|
|
||||||
$catchFailure = null;
|
$catchFailure = null;
|
||||||
$em->expects($this->once())
|
$em->expects($this->once())
|
||||||
->method('persist')
|
->method('persist')
|
||||||
->with($this->isInstanceOf('Alchemy\Phrasea\Model\Entities\AuthFailure'))
|
->with($this->isInstanceOf(AuthFailure::class))
|
||||||
->will($this->returnCallback(function ($failure) use (&$catchFailure) {
|
->will($this->returnCallback(function ($failure) use (&$catchFailure) {
|
||||||
$catchFailure = $failure;
|
$catchFailure = $failure;
|
||||||
}));
|
}));
|
||||||
@@ -54,6 +55,8 @@ class FailureManagerTest extends \PhraseanetTestCase
|
|||||||
$manager = new FailureManager($repo, $em, $recaptcha, 9);
|
$manager = new FailureManager($repo, $em, $recaptcha, 9);
|
||||||
$manager->saveFailure($username, $request);
|
$manager->saveFailure($username, $request);
|
||||||
|
|
||||||
|
/** @var null|AuthFailure $catchFailure */
|
||||||
|
$this->assertInstanceOf(AuthFailure::class, $catchFailure);
|
||||||
$this->assertEquals($ip, $catchFailure->getIp());
|
$this->assertEquals($ip, $catchFailure->getIp());
|
||||||
$this->assertEquals(true, $catchFailure->getLocked());
|
$this->assertEquals(true, $catchFailure->getLocked());
|
||||||
$this->assertEquals($username, $catchFailure->getUsername());
|
$this->assertEquals($username, $catchFailure->getUsername());
|
||||||
@@ -64,7 +67,7 @@ class FailureManagerTest extends \PhraseanetTestCase
|
|||||||
*/
|
*/
|
||||||
public function testCheckFailures()
|
public function testCheckFailures()
|
||||||
{
|
{
|
||||||
$repo = $this->getRepo();
|
$repo = $this->createAuthFailureRepositoryMock();
|
||||||
$em = $this->createEntityManagerMock();
|
$em = $this->createEntityManagerMock();
|
||||||
$recaptcha = $this->getReCaptchaMock(null);
|
$recaptcha = $this->getReCaptchaMock(null);
|
||||||
$request = $this->getRequestMock();
|
$request = $this->getRequestMock();
|
||||||
@@ -86,7 +89,7 @@ class FailureManagerTest extends \PhraseanetTestCase
|
|||||||
*/
|
*/
|
||||||
public function testCheckFailuresLessThan9()
|
public function testCheckFailuresLessThan9()
|
||||||
{
|
{
|
||||||
$repo = $this->getRepo();
|
$repo = $this->createAuthFailureRepositoryMock();
|
||||||
$em = $this->createEntityManagerMock();
|
$em = $this->createEntityManagerMock();
|
||||||
$recaptcha = $this->getReCaptchaMock(null);
|
$recaptcha = $this->getReCaptchaMock(null);
|
||||||
$request = $this->getRequestMock();
|
$request = $this->getRequestMock();
|
||||||
@@ -94,7 +97,7 @@ class FailureManagerTest extends \PhraseanetTestCase
|
|||||||
$username = 'romainneutron';
|
$username = 'romainneutron';
|
||||||
|
|
||||||
$oldFailures = $this->ArrayIze(function () {
|
$oldFailures = $this->ArrayIze(function () {
|
||||||
return $this->getMock('Alchemy\Phrasea\Model\Entities\AuthFailure');
|
return $this->getMock(AuthFailure::class);
|
||||||
}, 8);
|
}, 8);
|
||||||
|
|
||||||
$repo->expects($this->once())
|
$repo->expects($this->once())
|
||||||
@@ -110,7 +113,7 @@ class FailureManagerTest extends \PhraseanetTestCase
|
|||||||
*/
|
*/
|
||||||
public function testCheckFailuresMoreThan9WithoutCaptcha()
|
public function testCheckFailuresMoreThan9WithoutCaptcha()
|
||||||
{
|
{
|
||||||
$repo = $this->getRepo();
|
$repo = $this->createAuthFailureRepositoryMock();
|
||||||
$em = $this->createEntityManagerMock();
|
$em = $this->createEntityManagerMock();
|
||||||
$recaptcha = $this->getReCaptchaMock(false);
|
$recaptcha = $this->getReCaptchaMock(false);
|
||||||
$request = $this->getRequestMock();
|
$request = $this->getRequestMock();
|
||||||
@@ -118,7 +121,7 @@ class FailureManagerTest extends \PhraseanetTestCase
|
|||||||
$username = 'romainneutron';
|
$username = 'romainneutron';
|
||||||
|
|
||||||
$oldFailures = $this->ArrayIze(function () {
|
$oldFailures = $this->ArrayIze(function () {
|
||||||
return $this->getMock('Alchemy\Phrasea\Model\Entities\AuthFailure');
|
return $this->getMock(AuthFailure::class);
|
||||||
}, 10);
|
}, 10);
|
||||||
|
|
||||||
$repo->expects($this->once())
|
$repo->expects($this->once())
|
||||||
@@ -134,7 +137,7 @@ class FailureManagerTest extends \PhraseanetTestCase
|
|||||||
*/
|
*/
|
||||||
public function testCheckFailuresMoreThan9WithCorrectCaptcha()
|
public function testCheckFailuresMoreThan9WithCorrectCaptcha()
|
||||||
{
|
{
|
||||||
$repo = $this->getRepo();
|
$repo = $this->createAuthFailureRepositoryMock();
|
||||||
$em = $this->createEntityManagerMock();
|
$em = $this->createEntityManagerMock();
|
||||||
$request = $this->getRequestMock();
|
$request = $this->getRequestMock();
|
||||||
$recaptcha = $this->getReCaptchaMock(true, $request, true);
|
$recaptcha = $this->getReCaptchaMock(true, $request, true);
|
||||||
@@ -142,7 +145,7 @@ class FailureManagerTest extends \PhraseanetTestCase
|
|||||||
$username = 'romainneutron';
|
$username = 'romainneutron';
|
||||||
|
|
||||||
$oldFailures = $this->ArrayIze(function () {
|
$oldFailures = $this->ArrayIze(function () {
|
||||||
$failure = $this->getMock('Alchemy\Phrasea\Model\Entities\AuthFailure');
|
$failure = $this->getMock(AuthFailure::class);
|
||||||
$failure->expects($this->once())
|
$failure->expects($this->once())
|
||||||
->method('setLocked')
|
->method('setLocked')
|
||||||
->with($this->equalTo(false));
|
->with($this->equalTo(false));
|
||||||
@@ -164,7 +167,7 @@ class FailureManagerTest extends \PhraseanetTestCase
|
|||||||
*/
|
*/
|
||||||
public function testCheckFailuresMoreThan9WithIncorrectCaptcha()
|
public function testCheckFailuresMoreThan9WithIncorrectCaptcha()
|
||||||
{
|
{
|
||||||
$repo = $this->getRepo();
|
$repo = $this->createAuthFailureRepositoryMock();
|
||||||
$em = $this->createEntityManagerMock();
|
$em = $this->createEntityManagerMock();
|
||||||
$request = $this->getRequestMock();
|
$request = $this->getRequestMock();
|
||||||
$recaptcha = $this->getReCaptchaMock(true, $request, false);
|
$recaptcha = $this->getReCaptchaMock(true, $request, false);
|
||||||
@@ -172,7 +175,7 @@ class FailureManagerTest extends \PhraseanetTestCase
|
|||||||
$username = 'romainneutron';
|
$username = 'romainneutron';
|
||||||
|
|
||||||
$oldFailures = $this->ArrayIze(function () {
|
$oldFailures = $this->ArrayIze(function () {
|
||||||
return $this->getMock('Alchemy\Phrasea\Model\Entities\AuthFailure');
|
return $this->getMock(AuthFailure::class);
|
||||||
}, 10);
|
}, 10);
|
||||||
|
|
||||||
$repo->expects($this->once())
|
$repo->expects($this->once())
|
||||||
@@ -185,7 +188,7 @@ class FailureManagerTest extends \PhraseanetTestCase
|
|||||||
|
|
||||||
public function testCheckFailuresTrialsIsConfigurableUnderThreshold()
|
public function testCheckFailuresTrialsIsConfigurableUnderThreshold()
|
||||||
{
|
{
|
||||||
$repo = $this->getRepo();
|
$repo = $this->createAuthFailureRepositoryMock();
|
||||||
$em = $this->createEntityManagerMock();
|
$em = $this->createEntityManagerMock();
|
||||||
$recaptcha = $this->getReCaptchaMock(null);
|
$recaptcha = $this->getReCaptchaMock(null);
|
||||||
$request = $this->getRequestMock();
|
$request = $this->getRequestMock();
|
||||||
@@ -193,7 +196,7 @@ class FailureManagerTest extends \PhraseanetTestCase
|
|||||||
$username = 'romainneutron';
|
$username = 'romainneutron';
|
||||||
|
|
||||||
$oldFailures = $this->ArrayIze(function () {
|
$oldFailures = $this->ArrayIze(function () {
|
||||||
return $this->getMock('Alchemy\Phrasea\Model\Entities\AuthFailure');
|
return $this->getMock(AuthFailure::class);
|
||||||
}, 2);
|
}, 2);
|
||||||
|
|
||||||
$repo->expects($this->once())
|
$repo->expects($this->once())
|
||||||
@@ -207,10 +210,9 @@ class FailureManagerTest extends \PhraseanetTestCase
|
|||||||
public function testTrialsIsConfigurable()
|
public function testTrialsIsConfigurable()
|
||||||
{
|
{
|
||||||
$em = $this->createEntityManagerMock();
|
$em = $this->createEntityManagerMock();
|
||||||
|
|
||||||
$recaptcha = $this->getReCaptchaMock(null);
|
$recaptcha = $this->getReCaptchaMock(null);
|
||||||
|
|
||||||
$manager = new FailureManager($this->createEntityRepositoryMock(), $em, $recaptcha, 2);
|
$manager = new FailureManager($this->createAuthFailureRepositoryMock(), $em, $recaptcha, 2);
|
||||||
$this->assertEquals(2, $manager->getTrials());
|
$this->assertEquals(2, $manager->getTrials());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,7 +222,7 @@ class FailureManagerTest extends \PhraseanetTestCase
|
|||||||
*/
|
*/
|
||||||
public function testCheckFailuresTrialsIsConfigurableOverThreshold()
|
public function testCheckFailuresTrialsIsConfigurableOverThreshold()
|
||||||
{
|
{
|
||||||
$repo = $this->getRepo();
|
$repo = $this->createAuthFailureRepositoryMock();
|
||||||
$em = $this->createEntityManagerMock();
|
$em = $this->createEntityManagerMock();
|
||||||
$request = $this->getRequestMock();
|
$request = $this->getRequestMock();
|
||||||
$recaptcha = $this->getReCaptchaMock(true, $request, false);
|
$recaptcha = $this->getReCaptchaMock(true, $request, false);
|
||||||
@@ -228,7 +230,7 @@ class FailureManagerTest extends \PhraseanetTestCase
|
|||||||
$username = 'romainneutron';
|
$username = 'romainneutron';
|
||||||
|
|
||||||
$oldFailures = $this->ArrayIze(function () {
|
$oldFailures = $this->ArrayIze(function () {
|
||||||
return $this->getMock('Alchemy\Phrasea\Model\Entities\AuthFailure');
|
return $this->getMock(AuthFailure::class);
|
||||||
}, 3);
|
}, 3);
|
||||||
|
|
||||||
$repo->expects($this->once())
|
$repo->expects($this->once())
|
||||||
@@ -311,14 +313,17 @@ class FailureManagerTest extends \PhraseanetTestCase
|
|||||||
|
|
||||||
private function getRequestMock()
|
private function getRequestMock()
|
||||||
{
|
{
|
||||||
return $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')
|
return $this->getMockBuilder(Request::class)
|
||||||
->disableOriginalConstructor()
|
->disableOriginalConstructor()
|
||||||
->getMock();
|
->getMock();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getRepo()
|
/**
|
||||||
|
* @return AuthFailureRepository|\PHPUnit_Framework_MockObject_MockObject
|
||||||
|
*/
|
||||||
|
private function createAuthFailureRepositoryMock()
|
||||||
{
|
{
|
||||||
return $this->getMockBuilder('Alchemy\Phrasea\Model\Repositories\AuthFailureRepository')
|
return $this->getMockBuilder(AuthFailureRepository::class)
|
||||||
->disableOriginalConstructor()
|
->disableOriginalConstructor()
|
||||||
->getMock();
|
->getMock();
|
||||||
}
|
}
|
||||||
|
@@ -2,11 +2,26 @@
|
|||||||
|
|
||||||
namespace Alchemy\Tests\Phrasea\Core\Provider;
|
namespace Alchemy\Tests\Phrasea\Core\Provider;
|
||||||
|
|
||||||
|
use Alchemy\Phrasea\Authentication\AccountCreator;
|
||||||
|
use Alchemy\Phrasea\Authentication\Authenticator;
|
||||||
|
use Alchemy\Phrasea\Authentication\Manager as AuthenticationManager;
|
||||||
|
use Alchemy\Phrasea\Authentication\PersistentCookie\Manager as PersistentCookieManager;
|
||||||
|
use Alchemy\Phrasea\Authentication\Phrasea\FailureHandledNativeAuthentication;
|
||||||
|
use Alchemy\Phrasea\Authentication\Phrasea\FailureManager;
|
||||||
|
use Alchemy\Phrasea\Authentication\Phrasea\NativeAuthentication;
|
||||||
|
use Alchemy\Phrasea\Authentication\Phrasea\OldPasswordEncoder;
|
||||||
|
use Alchemy\Phrasea\Authentication\Phrasea\PasswordAuthenticationInterface;
|
||||||
|
use Alchemy\Phrasea\Authentication\Phrasea\PasswordEncoder;
|
||||||
|
use Alchemy\Phrasea\Authentication\Provider\Factory;
|
||||||
|
use Alchemy\Phrasea\Authentication\ProvidersCollection;
|
||||||
|
use Alchemy\Phrasea\Authentication\SuggestionFinder;
|
||||||
use Alchemy\Phrasea\Core\Provider\RepositoriesServiceProvider;
|
use Alchemy\Phrasea\Core\Provider\RepositoriesServiceProvider;
|
||||||
use Alchemy\Phrasea\Core\Provider\TokensServiceProvider;
|
|
||||||
use Alchemy\Phrasea\Core\Provider\AuthenticationManagerServiceProvider;
|
use Alchemy\Phrasea\Core\Provider\AuthenticationManagerServiceProvider;
|
||||||
use Alchemy\Phrasea\Core\Provider\ConfigurationServiceProvider;
|
use Alchemy\Phrasea\Core\Provider\ConfigurationServiceProvider;
|
||||||
|
use Alchemy\Phrasea\Model\Entities\User;
|
||||||
|
use Alchemy\Phrasea\Model\Repositories\AuthFailureRepository;
|
||||||
use Alchemy\Phrasea\Model\Repositories\UserRepository;
|
use Alchemy\Phrasea\Model\Repositories\UserRepository;
|
||||||
|
use Neutron\ReCaptcha\ReCaptcha;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @group functional
|
* @group functional
|
||||||
@@ -19,59 +34,59 @@ class AuthenticationManagerServiceProviderTest extends ServiceProviderTestCase
|
|||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
[
|
[
|
||||||
'Alchemy\Phrasea\Core\Provider\AuthenticationManagerServiceProvider',
|
AuthenticationManagerServiceProvider::class,
|
||||||
'authentication',
|
'authentication',
|
||||||
'Alchemy\\Phrasea\\Authentication\\Authenticator',
|
Authenticator::class,
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Alchemy\Phrasea\Core\Provider\AuthenticationManagerServiceProvider',
|
AuthenticationManagerServiceProvider::class,
|
||||||
'authentication.persistent-manager',
|
'authentication.persistent-manager',
|
||||||
'Alchemy\Phrasea\Authentication\PersistentCookie\Manager'
|
PersistentCookieManager::class
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Alchemy\Phrasea\Core\Provider\AuthenticationManagerServiceProvider',
|
AuthenticationManagerServiceProvider::class,
|
||||||
'authentication.suggestion-finder',
|
'authentication.suggestion-finder',
|
||||||
'Alchemy\Phrasea\Authentication\SuggestionFinder'
|
SuggestionFinder::class
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Alchemy\Phrasea\Core\Provider\AuthenticationManagerServiceProvider',
|
AuthenticationManagerServiceProvider::class,
|
||||||
'authentication.providers.factory',
|
'authentication.providers.factory',
|
||||||
'Alchemy\Phrasea\Authentication\Provider\Factory'
|
Factory::class
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Alchemy\Phrasea\Core\Provider\AuthenticationManagerServiceProvider',
|
AuthenticationManagerServiceProvider::class,
|
||||||
'authentication.providers',
|
'authentication.providers',
|
||||||
'Alchemy\Phrasea\Authentication\ProvidersCollection'
|
ProvidersCollection::class
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Alchemy\Phrasea\Core\Provider\AuthenticationManagerServiceProvider',
|
AuthenticationManagerServiceProvider::class,
|
||||||
'authentication.manager',
|
'authentication.manager',
|
||||||
'Alchemy\Phrasea\Authentication\Manager'
|
AuthenticationManager::class
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Alchemy\Phrasea\Core\Provider\AuthenticationManagerServiceProvider',
|
AuthenticationManagerServiceProvider::class,
|
||||||
'auth.password-encoder',
|
'auth.password-encoder',
|
||||||
'Alchemy\Phrasea\Authentication\Phrasea\PasswordEncoder'
|
PasswordEncoder::class
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Alchemy\Phrasea\Core\Provider\AuthenticationManagerServiceProvider',
|
AuthenticationManagerServiceProvider::class,
|
||||||
'auth.old-password-encoder',
|
'auth.old-password-encoder',
|
||||||
'Alchemy\Phrasea\Authentication\Phrasea\OldPasswordEncoder'
|
OldPasswordEncoder::class
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Alchemy\Phrasea\Core\Provider\AuthenticationManagerServiceProvider',
|
AuthenticationManagerServiceProvider::class,
|
||||||
'auth.native.failure-manager',
|
'auth.native.failure-manager',
|
||||||
'Alchemy\Phrasea\Authentication\Phrasea\FailureManager'
|
FailureManager::class
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Alchemy\Phrasea\Core\Provider\AuthenticationManagerServiceProvider',
|
AuthenticationManagerServiceProvider::class,
|
||||||
'auth.native',
|
'auth.native',
|
||||||
'Alchemy\Phrasea\Authentication\Phrasea\PasswordAuthenticationInterface'
|
PasswordAuthenticationInterface::class
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
'Alchemy\Phrasea\Core\Provider\AuthenticationManagerServiceProvider',
|
AuthenticationManagerServiceProvider::class,
|
||||||
'authentication.providers.account-creator',
|
'authentication.providers.account-creator',
|
||||||
'Alchemy\Phrasea\Authentication\AccountCreator'
|
AccountCreator::class
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@@ -83,9 +98,7 @@ class AuthenticationManagerServiceProviderTest extends ServiceProviderTestCase
|
|||||||
$app['conf']->set(['authentication', 'captcha', 'trials-before-display'], 42);
|
$app['conf']->set(['authentication', 'captcha', 'trials-before-display'], 42);
|
||||||
|
|
||||||
//$app['orm.em'] = $this->createEntityManagerMock();
|
//$app['orm.em'] = $this->createEntityManagerMock();
|
||||||
$app['recaptcha'] = $this->getMockBuilder('Neutron\ReCaptcha\ReCaptcha')
|
$app['recaptcha'] = $this->createReCaptchaMock();
|
||||||
->disableOriginalConstructor()
|
|
||||||
->getMock();
|
|
||||||
|
|
||||||
$manager = $app['auth.native.failure-manager'];
|
$manager = $app['auth.native.failure-manager'];
|
||||||
$this->assertEquals(42, $manager->getTrials());
|
$this->assertEquals(42, $manager->getTrials());
|
||||||
@@ -93,9 +106,10 @@ class AuthenticationManagerServiceProviderTest extends ServiceProviderTestCase
|
|||||||
|
|
||||||
public function testFailureAccountCreator()
|
public function testFailureAccountCreator()
|
||||||
{
|
{
|
||||||
self::$DI['app']->register(new ConfigurationServiceProvider());
|
$app = $this->getApplication();
|
||||||
self::$DI['app']['conf']->set(['authentication', 'auto-create'], ['templates' => []]);
|
$app->register(new ConfigurationServiceProvider());
|
||||||
self::$DI['app']['authentication.providers.account-creator'];
|
$app['conf']->set(['authentication', 'auto-create'], ['templates' => []]);
|
||||||
|
$app['authentication.providers.account-creator'];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAuthNativeWithCaptchaEnabled()
|
public function testAuthNativeWithCaptchaEnabled()
|
||||||
@@ -111,12 +125,12 @@ class AuthenticationManagerServiceProviderTest extends ServiceProviderTestCase
|
|||||||
|
|
||||||
$app['orm.em'] = $this->createEntityManagerMock();
|
$app['orm.em'] = $this->createEntityManagerMock();
|
||||||
$app['repo.users'] = $this->createUserRepositoryMock();
|
$app['repo.users'] = $this->createUserRepositoryMock();
|
||||||
$app['repo.auth-failures'] = $this->createEntityRepositoryMock();
|
$app['repo.auth-failures'] = $this->getMockBuilder(AuthFailureRepository::class)
|
||||||
$app['recaptcha'] = $this->getMockBuilder('Neutron\ReCaptcha\ReCaptcha')
|
|
||||||
->disableOriginalConstructor()
|
->disableOriginalConstructor()
|
||||||
->getMock();
|
->getMock();
|
||||||
|
$app['recaptcha'] = $this->createReCaptchaMock();
|
||||||
|
|
||||||
$this->assertInstanceOf('Alchemy\Phrasea\Authentication\Phrasea\FailureHandledNativeAuthentication', $app['auth.native']);
|
$this->assertInstanceOf(FailureHandledNativeAuthentication::class, $app['auth.native']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAuthNativeWithCaptchaDisabled()
|
public function testAuthNativeWithCaptchaDisabled()
|
||||||
@@ -131,26 +145,25 @@ class AuthenticationManagerServiceProviderTest extends ServiceProviderTestCase
|
|||||||
|
|
||||||
$app['orm.em'] = $this->createEntityManagerMock();
|
$app['orm.em'] = $this->createEntityManagerMock();
|
||||||
$app['repo.users'] = $this->createUserRepositoryMock();
|
$app['repo.users'] = $this->createUserRepositoryMock();
|
||||||
$app['recaptcha'] = $this->getMockBuilder('Neutron\ReCaptcha\ReCaptcha')
|
$app['recaptcha'] = $this->createReCaptchaMock();
|
||||||
->disableOriginalConstructor()
|
|
||||||
->getMock();
|
|
||||||
|
|
||||||
$this->assertInstanceOf('Alchemy\Phrasea\Authentication\Phrasea\NativeAuthentication', $app['auth.native']);
|
$this->assertInstanceOf(NativeAuthentication::class, $app['auth.native']);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testAccountCreator()
|
public function testAccountCreator()
|
||||||
{
|
{
|
||||||
$template1 = $user = self::$DI['app']['manipulator.user']->createTemplate('template1', self::$DI['user']);
|
$app = $this->getApplication();
|
||||||
$template2 = $user = self::$DI['app']['manipulator.user']->createTemplate('template2', self::$DI['user']);
|
$template1 = $user = $app['manipulator.user']->createTemplate('template1', self::$DI['user']);
|
||||||
|
$template2 = $user = $app['manipulator.user']->createTemplate('template2', self::$DI['user']);
|
||||||
|
|
||||||
self::$DI['app']['conf']->set(['authentication', 'auto-create'], ['templates' => [$template1->getId(), $template2->getId()]]);
|
$app['conf']->set(['authentication', 'auto-create'], ['templates' => [$template1->getId(), $template2->getId()]]);
|
||||||
|
|
||||||
$this->assertEquals([$template1->getLogin(), $template2->getLogin()], array_map(function ($u) {
|
$this->assertEquals([$template1->getLogin(), $template2->getLogin()], array_map(function (User $user) {
|
||||||
return $u->getLogin();
|
return $user->getLogin();
|
||||||
}, self::$DI['app']['authentication.providers.account-creator']->getTemplates()));
|
}, $app['authentication.providers.account-creator']->getTemplates()));
|
||||||
|
|
||||||
$this->removeUser(self::$DI['app'], $template1);
|
$this->removeUser($app, $template1);
|
||||||
$this->removeUser(self::$DI['app'], $template2);
|
$this->removeUser($app, $template2);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function createUserRepositoryMock()
|
private function createUserRepositoryMock()
|
||||||
@@ -159,4 +172,14 @@ class AuthenticationManagerServiceProviderTest extends ServiceProviderTestCase
|
|||||||
->disableOriginalConstructor()
|
->disableOriginalConstructor()
|
||||||
->getMock();
|
->getMock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ReCaptcha|\PHPUnit_Framework_MockObject_MockObject
|
||||||
|
*/
|
||||||
|
protected function createReCaptchaMock()
|
||||||
|
{
|
||||||
|
return $this->getMockBuilder(ReCaptcha::class)
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->getMock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -336,6 +336,11 @@ abstract class PhraseanetTestCase extends WebTestCase
|
|||||||
return $cli;
|
return $cli;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param null|string $path
|
||||||
|
* @param string $environment
|
||||||
|
* @return Application
|
||||||
|
*/
|
||||||
protected function loadApp($path = null, $environment = Application::ENV_TEST)
|
protected function loadApp($path = null, $environment = Application::ENV_TEST)
|
||||||
{
|
{
|
||||||
if (null !== $path) {
|
if (null !== $path) {
|
||||||
|
Reference in New Issue
Block a user