Skip to content

Commit

Permalink
ready for initial release
Browse files Browse the repository at this point in the history
  • Loading branch information
tarach committed Dec 2, 2023
1 parent a03211b commit 350004a
Show file tree
Hide file tree
Showing 12 changed files with 249 additions and 59 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
vendor/
.idea/
ssl-cert/
4 changes: 2 additions & 2 deletions bin/create
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ $phar->buildFromDirectory(
'/vendor|src|bin\\/console.*/',
);
$phar->setDefaultStub('bin/console.php');
$phar->compress(Phar::GZ);
$phar->compress(Phar::BZ2);
//$phar->compress(Phar::GZ);
//$phar->compress(Phar::BZ2);
32 changes: 32 additions & 0 deletions src/Command/Config/ConfigSchema.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace Tarach\SelfSignedCert\Command\Config;

class ConfigSchema
{
public function __construct(
private readonly array $config
) {
}

public function hasSchema(string $name): bool
{
return array_key_exists($name, $this->config);
}

public function getConfig(string $name): Config
{
if (!$this->hasSchema($name)) {
throw new \InvalidArgumentException(sprintf('Schema [%s] is not defined in config.', $name));
}

return new Config($this->config[$name]);
}

public function getAllSchemas(): array
{
return array_keys($this->config);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@
use Tarach\SelfSignedCert\Command\OptionsCollection;
use Tarach\SelfSignedCert\Command\QuestionCollectionFactory;

readonly class ConfigLoader
readonly class ConfigSchemaLoader
{
public function __construct(
private QuestionCollectionFactory $questionFactory,
private OptionsCollection $options,
){
}

public function load(string $configsString, InputInterface $input, InputDefinition $inputDefinition): Config
public function load(string $configsString, InputInterface $input, InputDefinition $inputDefinition): ConfigSchema
{
$configs = [];

Expand All @@ -37,27 +37,29 @@ public function load(string $configsString, InputInterface $input, InputDefiniti
);
}

// Load default value as first element
array_unshift($configs, $this->loadDefaultValues($input));
$configFromFiles = $this->processConfig($configs);
$schemas = $configFromFiles->getAllSchemas();

// Load configuration from options
$configs[] = $this->loadConfigFromOptions($input, $inputDefinition);
$configs[] = $this->applyToSchemas(
$schemas,
$this->loadConfigFromOptions($input, $inputDefinition)
);

$processor = new Processor();
$definition = new ConfigurationDefinition();
$processedConfiguration = $processor->processConfiguration(
$definition,
$configs
// Load default configuration
array_unshift($configs, $this->applyToSchemas(
$schemas,
$this->loadDefaultValues($input))
);

return new Config($processedConfiguration);
return $this->processConfig($configs);
}

private function loadConfigFromOptions(InputInterface $input, InputDefinition $inputDefinition): array
{
$config = [];

foreach ($this->getUsedOptions($input) as $optionName => $value)
foreach ($this->getUsedOptions($input) as $optionName)
{
$option = $inputDefinition->getOption($optionName);
if (!($option instanceof ConfigOverrideInterface)) {
Expand Down Expand Up @@ -104,7 +106,11 @@ private function loadDefaultValues(InputInterface $input): array

private function getUsedOptions(InputInterface $input): array
{
return (new \ReflectionObject($input))->getProperty('options')->getValue($input);
return array_keys(
(new \ReflectionObject($input))
->getProperty('options')
->getValue($input)
);
}

private function &getElementInArrayToSet(array &$config, array $path)
Expand All @@ -120,4 +126,31 @@ private function &getElementInArrayToSet(array &$config, array $path)

return $this->getElementInArrayToSet($config[$key], $path);
}

private function processConfig(array $configs): ConfigSchema
{
$processor = new Processor();
$definition = new ConfigurationDefinition();
$processedConfiguration = $processor->processConfiguration(
$definition,
$configs
);

return new ConfigSchema($processedConfiguration);
}

private function applyToSchemas(array $schemas, array $configOptions): array
{
if (empty($configOptions)) {
return [];
}

$config = [];
foreach ($schemas as $schema)
{
$config[$schema] = $configOptions;
}

return $config;
}
}
4 changes: 3 additions & 1 deletion src/Command/Config/ConfigurationDefinition.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ class ConfigurationDefinition implements ConfigurationInterface
public function getConfigTreeBuilder(): TreeBuilder
{
$treeBuilder = new TreeBuilder('sslgen');
$node = $treeBuilder->getRootNode();

$treeBuilder->getRootNode()
$node
->arrayPrototype()
->children()
->arrayNode(Config::KEY_AUTHORITY)
->children()
Expand Down
4 changes: 3 additions & 1 deletion src/Command/Option/ConfigOption.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@

class ConfigOption extends AbstractInputOption
{
public const NAME = 'config';

public function __construct(string|bool|int|float|array $default = null)
{
parent::__construct(
'config',
self::NAME,
'c',
InputOption::VALUE_REQUIRED,
'Path to yaml configuration file(s). Or multiple comma separated files.',
Expand Down
22 changes: 22 additions & 0 deletions src/Command/Option/SchemaOption.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace Tarach\SelfSignedCert\Command\Option;

use Symfony\Component\Console\Input\InputOption;

class SchemaOption extends AbstractInputOption
{
public const NAME = 'schema';

public function __construct()
{
parent::__construct(
self::NAME,
'e',
InputOption::VALUE_REQUIRED,
'Name or number of configuration schema to use.',
);
}
}
2 changes: 2 additions & 0 deletions src/Command/OptionsCollectionFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Tarach\SelfSignedCert\Command\Option\ConfigOption;
use Tarach\SelfSignedCert\Command\Option\DirectoryOption;
use Tarach\SelfSignedCert\Command\Option\OverwriteOption;
use Tarach\SelfSignedCert\Command\Option\SchemaOption;
use Tarach\SelfSignedCert\Command\Option\SkipOption;

class OptionsCollectionFactory
Expand All @@ -22,6 +23,7 @@ public function __construct()
AuthorityCertificateOption::class,
OverwriteOption::class,
SkipOption::class,
SchemaOption::class,
];
}

Expand Down
2 changes: 1 addition & 1 deletion src/SSLExporterService.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public function toFiles(SSLGeneratorOutput $ssl, string $directory): void

private function normalizeDirectoryPath(string $directory): string
{
$directory = rtrim($directory, '\\/') . DIRECTORY_SEPARATOR;
$directory = realpath(rtrim($directory, '\\/')) . DIRECTORY_SEPARATOR;

if (!file_exists($directory)) {
if (!@mkdir($directory)) {
Expand Down
81 changes: 78 additions & 3 deletions src/SSLGenerateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Tarach\SelfSignedCert;

use Exception;
use InvalidArgumentException;
use Monolog\Handler\StreamHandler;
use Monolog\Level;
use Monolog\Logger;
Expand All @@ -13,8 +14,11 @@
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;
use Tarach\SelfSignedCert\Command\Config\Config;
use Tarach\SelfSignedCert\Command\Config\ConfigLoader;
use Tarach\SelfSignedCert\Command\Config\ConfigSchemaLoader;
use Tarach\SelfSignedCert\Command\Option\ConfigOption;
use Tarach\SelfSignedCert\Command\Option\SchemaOption;
use Tarach\SelfSignedCert\Command\OptionsCollection;
use Tarach\SelfSignedCert\Command\OptionsCollectionFactory;
use Tarach\SelfSignedCert\Command\QuestionCollectionFactory;
Expand Down Expand Up @@ -58,13 +62,24 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$logger = $this->createLogger($output->getVerbosity());

try {
$configLoader = new ConfigLoader($this->questionFactory, $this->options);
$config = $configLoader->load($input->getOption('config'), $input, $this->getDefinition());
$configSchemaLoader = new ConfigSchemaLoader($this->questionFactory, $this->options);
$configSchema = $configSchemaLoader->load($input->getOption(ConfigOption::NAME), $input, $this->getDefinition());
} catch (Exception $exception) {
$logger->error($exception->getMessage());
return self::FAILURE;
}

$schemas = $configSchema->getAllSchemas();
$schema = $this->selectSchema($schemas, $input, $output);
if (!$schema) {
$logger->error('Wrong schema selected.');
return self::FAILURE;
}

$logger->info(sprintf('Using schema [%s].', $schema));

$config = $configSchema->getConfig($schema);

$directory = $config->getOutputDirectory();
$overwrite = $config->isOverwriteEnabled();

Expand Down Expand Up @@ -141,4 +156,64 @@ private function addInputOption(InputOption $inputOption): void
assert(!$this->getDefinition()->hasOption($inputOption->getName()));
$this->getDefinition()->addOption($inputOption);
}

private function selectSchema(array $schemas, InputInterface $input, OutputInterface $output): ?string
{
if (empty($schemas)) {
throw new InvalidArgumentException('There must be at least one schema.');
}

if (1 === count($schemas)) {
return array_pop($schemas);
}

$schema = $input->getOption(SchemaOption::NAME);
if (!empty($schema)) {
$schema = $this->getSelectedSchema($schemas, $schema);
if (!$schema) {
return null;
}
return $schema;
}

return $this->userSelectSchema($schemas, $input, $output);
}

private function userSelectSchema(array $schemas, InputInterface $input, OutputInterface $output): string
{
$helper = $this->getHelper('question');

$question = '';
foreach ($schemas as $index => $schema)
{
$index += 1;
$question .= sprintf("[%s] %s\n", $index, $schema);
}

$question .= 'Choose schema: ';

$schema = null;
do {
$index = $helper->ask($input, $output, new Question($question));
$index -= 1;
if (array_key_exists($index, $schemas)) {
$schema = $schemas[$index];
}
} while (!$schema);

return $schema;
}

private function getSelectedSchema(array $schemas, mixed $schema): ?string
{
if (in_array($schema, $schemas)) {
return $schema;
}

if (array_key_exists($schema - 1, $schemas)) {
return $schemas[$schema - 1];
}

return null;
}
}
Loading

0 comments on commit 350004a

Please sign in to comment.