Skip to content
This repository has been archived by the owner on Mar 1, 2023. It is now read-only.

Commit

Permalink
finished #63
Browse files Browse the repository at this point in the history
  • Loading branch information
prisis committed Sep 6, 2018
1 parent 598f9ba commit 762f379
Show file tree
Hide file tree
Showing 18 changed files with 1,557 additions and 153 deletions.
87 changes: 79 additions & 8 deletions src/Automatic/Automatic.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@
use Narrowspark\Automatic\Prefetcher\ParallelDownloader;
use Narrowspark\Automatic\Prefetcher\Prefetcher;
use Narrowspark\Automatic\Prefetcher\TruncatedComposerRepository;
use Narrowspark\Automatic\Security\Audit;
use Narrowspark\Automatic\Security\Command\AuditCommandProvider;
use Narrowspark\Automatic\Security\Downloader;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use ReflectionClass;
Expand Down Expand Up @@ -106,10 +108,26 @@ class Automatic implements PluginInterface, EventSubscriberInterface, Capable
private $operations = [];

/**
* @var array
* List of package messages.
*
* @var string[]
*/
private $postInstallOutput = [''];

/**
* The SecurityAdvisories database.
*
* @var array<string, array>
*/
private $securityAdvisories;

/**
* Found package vulnerabilities.
*
* @var array[]
*/
private $foundVulnerabilities = [];

/**
* Get the Container instance.
*
Expand All @@ -136,8 +154,8 @@ public static function getSubscribedEvents(): array
InstallerEvents::POST_DEPENDENCIES_SOLVING => [['populateFilesCacheDir', \PHP_INT_MAX]],
PackageEvents::PRE_PACKAGE_INSTALL => [['populateFilesCacheDir', ~\PHP_INT_MAX]],
PackageEvents::PRE_PACKAGE_UPDATE => [['populateFilesCacheDir', ~\PHP_INT_MAX]],
PackageEvents::POST_PACKAGE_INSTALL => 'record',
PackageEvents::POST_PACKAGE_UPDATE => 'record',
PackageEvents::POST_PACKAGE_INSTALL => [['record'], ['audit']],
PackageEvents::POST_PACKAGE_UPDATE => [['record'], ['audit']],
PackageEvents::POST_PACKAGE_UNINSTALL => 'record',
PluginEvents::PRE_FILE_DOWNLOAD => 'onFileDownload',
ScriptEvents::POST_INSTALL_CMD => 'onPostInstall',
Expand Down Expand Up @@ -180,6 +198,16 @@ public function activate(Composer $composer, IOInterface $io): void

$this->container = new Container($composer, $io);

$extra = $this->container->get('composer-extra');
$downloader = new Downloader();

if (isset($extra[Util::COMPOSER_EXTRA_KEY]['audit']['timeout'])) {
$downloader->setTimeout($extra[Util::COMPOSER_EXTRA_KEY]['audit']['timeout']);
}
$this->container->set(Audit::class, static function (Container $container) use ($downloader) {
return new Audit($container->get('vendor-dir'), $downloader);
});

/** @var \Composer\Installer\InstallationManager $installationManager */
$installationManager = $this->container->get(Composer::class)->getInstallationManager();
$installationManager->addInstaller($this->container->get(ConfiguratorInstaller::class));
Expand All @@ -188,7 +216,7 @@ public function activate(Composer $composer, IOInterface $io): void
/** @var \Narrowspark\Automatic\LegacyTagsManager $tagsManager */
$tagsManager = $this->container->get(LegacyTagsManager::class);

$this->configureLegacyTagsManager($io, $tagsManager);
$this->configureLegacyTagsManager($io, $tagsManager, $extra);

$composer->setRepositoryManager($this->extendRepositoryManager($composer, $io, $tagsManager));

Expand All @@ -206,6 +234,8 @@ public function activate(Composer $composer, IOInterface $io): void
$container->get(InputInterface::class)
);
});

$this->securityAdvisories = $this->container->get(Audit::class)->getSecurityAdvisories($this->container->get(IOInterface::class));
}

/**
Expand All @@ -219,7 +249,18 @@ public function postInstallOut(Event $event): void
{
$event->stopPropagation();

$this->container->get(IOInterface::class)->write($this->postInstallOutput);
/** @var \Composer\IO\IOInterface $io */
$io = $this->container->get(IOInterface::class);

$io->write($this->postInstallOutput);

$count = \count(\array_filter($this->foundVulnerabilities));

if ($count !== 0) {
$io->write('<error>[!]</> Audit Security Report: ' . \sprintf('%s vulnerabilit%s found - run "composer audit" for more information', $count, $count === 1 ? 'y' : 'ies'));
} else {
$io->write('<fg=black;bg=green>[+]</> Audit Security Report: No known vulnerabilities found');
}
}

/**
Expand All @@ -244,6 +285,36 @@ public function record(PackageEvent $event): void
}
}

/**
* Audit composer package operations.
*
* @param \Composer\Installer\PackageEvent $event
*
* @return void
*/
public function audit(PackageEvent $event): void
{
$operation = $event->getOperation();

if ($operation instanceof UninstallOperation) {
return;
}

if ($operation instanceof UpdateOperation) {
$composerPackage = $operation->getTargetPackage();
} else {
$composerPackage = $operation->getPackage();
}

[$vulnerabilities, $messages] = $this->container->get(Audit::class)->checkPackage(
$composerPackage->getName(),
$composerPackage->getVersion(),
$this->securityAdvisories
);

$this->foundVulnerabilities += $vulnerabilities;
}

/**
* Execute on composer create project event.
*
Expand Down Expand Up @@ -303,7 +374,7 @@ public function runSkeletonGenerator(Event $event): void
$lock->read();

if ($lock->has(SkeletonInstaller::LOCK_KEY)) {
$this->operations = [];
$this->operations = $this->foundVulnerabilities = [];

$skeletonGenerator = new SkeletonGenerator(
$this->container->get(IOInterface::class),
Expand Down Expand Up @@ -877,12 +948,12 @@ private static function getComposerVersion(): string
*
* @param \Composer\IO\IOInterface $io
* @param \Narrowspark\Automatic\LegacyTagsManager $tagsManager
* @param array $extra
*
* @return void
*/
private function configureLegacyTagsManager(IOInterface $io, LegacyTagsManager $tagsManager): void
private function configureLegacyTagsManager(IOInterface $io, LegacyTagsManager $tagsManager, array $extra): void
{
$extra = $this->container->get('composer-extra');
$envRequire = \getenv('AUTOMATIC_REQUIRE');

if ($envRequire !== false) {
Expand Down
7 changes: 1 addition & 6 deletions src/Automatic/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -164,12 +164,7 @@ public function __construct(Composer $composer, IOInterface $io)
}

/**
* Set a new entry to the container.
*
* @param string $id
* @param callable $callback
*
* @return void
* {@inheritdoc}
*/
public function set(string $id, callable $callback): void
{
Expand Down
10 changes: 10 additions & 0 deletions src/Automatic/Contract/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ interface Container
*/
public function get(string $id);

/**
* Set a new entry to the container.
*
* @param string $id
* @param callable $callback
*
* @return void
*/
public function set(string $id, callable $callback): void;

/**
* Returns all container entries.
*
Expand Down
32 changes: 0 additions & 32 deletions src/Automatic/Contract/Crawler.php

This file was deleted.

18 changes: 18 additions & 0 deletions src/Automatic/Contract/Security/Formatter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
namespace Narrowspark\Automatic\Contract\Security;

use Symfony\Component\Console\Style\SymfonyStyle;

interface Formatter
{
/**
* Displays a security report.
*
* @param \Symfony\Component\Console\Style\SymfonyStyle $output
* @param array $vulnerabilities An array of vulnerabilities
*
* @return void
*/
public function displayResults(SymfonyStyle $output, array $vulnerabilities): void;
}
Loading

0 comments on commit 762f379

Please sign in to comment.