1.0.0 Alpha Release #59

Merged
netkas merged 213 commits from v1.0.0_alpha into master 2023-01-29 23:27:58 +00:00
3 changed files with 215 additions and 19 deletions
Showing only changes of commit 8bda6da2dc - Show all commits

View file

@ -2,9 +2,14 @@
namespace ncc\CLI; namespace ncc\CLI;
use Exception;
use ncc\Abstracts\Scopes; use ncc\Abstracts\Scopes;
use ncc\Exceptions\AccessDeniedException; use ncc\Managers\CredentialManager;
use ncc\Objects\CliHelpSection; use ncc\Objects\CliHelpSection;
use ncc\Objects\Vault\Password\AccessToken;
use ncc\Objects\Vault\Password\UsernamePassword;
use ncc\Utilities\Console;
use ncc\Utilities\Functions;
use ncc\Utilities\Resolver; use ncc\Utilities\Resolver;
class CredentialMenu class CredentialMenu
@ -14,7 +19,7 @@
* *
* @param $args * @param $args
* @return void * @return void
* @throws AccessDeniedException * @noinspection PhpNoReturnAttributeCanBeAddedInspection
*/ */
public static function start($args): void public static function start($args): void
{ {
@ -31,18 +36,120 @@
/** /**
* @param $args * @param $args
* @return void * @return void
* @throws AccessDeniedException
*/ */
public static function addCredential($args): void public static function addCredential($args): void
{ {
$ResolvedScope = Resolver::resolveScope(); $ResolvedScope = Resolver::resolveScope();
if($ResolvedScope !== Scopes::System) if($ResolvedScope !== Scopes::System)
Console::outError('Insufficient permissions to add credentials');
// Really dumb-proofing this
$name = $args['alias'] ?? $args['name'] ?? null;
$auth_type = $args['auth-type'] ?? $args['auth'] ?? null;
$username = $args['username'] ?? $args['usr'] ?? null;
$password = $args['password'] ?? $args['pwd'] ?? null;
$token = $args['token'] ?? $args['pat'] ?? $args['private-token'] ?? null;
$encrypt = $args['encrypt'] ?? $args['encrypted'] ?? null;
if($name === null)
$name = Console::getInput('Enter a name for the entry: ');
if($auth_type === null)
$auth_type = Console::getInput('Enter the authentication type (login or pat): ');
if($auth_type === 'login')
{ {
throw new AccessDeniedException('Root permissions are required to manage the vault'); if($username === null)
$username = Console::getInput('Username: ');
if($password === null)
$password = Console::passwordInput('Password: ');
}
elseif($auth_type === 'pat')
{
if($token === null)
$token = Console::passwordInput('Token: ');
}
else
{
Console::outError('Invalid authentication type');
} }
print('end' . PHP_EOL); if($encrypt === null)
$encrypt = Console::getBooleanInput('Encrypt entry with your password?');
if($name === null)
{
Console::outError('You must specify a name for the entry (alias, name)', true, 1);
return;
}
if($auth_type === null)
{
Console::outError('You must specify an authentication type for the entry (auth-type, auth)', true, 1);
return;
}
$encrypt = Functions::cbool($encrypt);
switch($auth_type)
{
case 'login':
if($username === null)
{
Console::outError('You must specify a username for the entry (username, usr)', true, 1);
return;
}
if($password === null)
{
Console::outError('You must specify a password for the entry (password, pwd)', true, 1);
return;
}
$pass_object = new UsernamePassword();
$pass_object->setUsername($username);
$pass_object->setPassword($password);
break;
case 'pat':
if($token === null)
{
Console::outError('You must specify a token for the entry (token, pat, private-token)', true, 1);
return;
}
$pass_object = new AccessToken();
$pass_object->setAccessToken($token);
break;
default:
Console::outError('Invalid authentication type specified', true, 1);
return;
}
$credential_manager = new CredentialManager();
if(!$credential_manager->getVault()->addEntry($name, $pass_object, $encrypt))
{
Console::outError('Failed to add entry, entry already exists.', true, 1);
return;
}
try
{
$credential_manager->saveVault();
}
catch(Exception $e)
{
Console::outException('Failed to save vault', $e, 1);
return;
}
Console::out('Successfully added entry', true, 0);
exit(0); exit(0);
} }
@ -53,20 +160,43 @@
*/ */
private static function displayOptions(): void private static function displayOptions(): void
{ {
$options = [ Console::out('Usage: ncc vault {command} [options]');
Console::out('Options:');
Console::outHelpSections([
new CliHelpSection(['help'], 'Displays this help menu about the value command'), new CliHelpSection(['help'], 'Displays this help menu about the value command'),
new CliHelpSection(['add'], 'Adds a new credential to the vault'), new CliHelpSection(['add'], 'Adds a new entry to the vault (See below)'),
new CliHelpSection(['remove'], 'Adds a new credential to the vault'), new CliHelpSection(['remove', '--name'], 'Removes'),
]; ]);
Console::out((string)null);
$options_padding = \ncc\Utilities\Functions::detectParametersPadding($options) + 4; Console::out('If you are adding a new entry, you can run the add command in interactive mode');
Console::out('or you can specify the options below' . PHP_EOL);
print('Usage: ncc vault {command} [options]' . PHP_EOL); Console::out('Add Options:');
print('Options:' . PHP_EOL); Console::outHelpSections([
foreach($options as $option) new CliHelpSection(['--name'], 'The name of the entry'),
{ new CliHelpSection(['--auth-type', '--auth'], 'The type of authentication (login, pat)'),
print(' ' . $option->toString($options_padding) . PHP_EOL); new CliHelpSection(['--encrypted', '--encrypt'], 'Whether or not to encrypt the entry', true),
} ]);
print(PHP_EOL);
Console::out(' login authentication type options:');
Console::outHelpSections([
new CliHelpSection(['--username', '--usr'], 'The username for the entry'),
new CliHelpSection(['--password', '--pwd'], 'The password for the entry'),
]);
Console::out(' pat authentication type options:');
Console::outHelpSections([
new CliHelpSection(['--token', '--pat',], 'The private access token for the entry', true),
]);
Console::out('Authentication Types:');
Console::out(' login');
Console::out(' pat' . PHP_EOL);
Console::out('Examples:');
Console::out(' ncc vault add --alias "My Alias" --auth-type login --username "myusername" --password "mypassword" --encrypt');
Console::out(' ncc vault add --alias "My Alias" --auth-type pat --token "mytoken"');
Console::out(' ncc vault remove --alias "My Alias"');
} }
} }

View file

@ -1,4 +1,4 @@
<?php <?php /** @noinspection PhpMissingFieldTypeInspection */
namespace ncc\Utilities; namespace ncc\Utilities;
@ -7,6 +7,8 @@
use ncc\Abstracts\LogLevel; use ncc\Abstracts\LogLevel;
use ncc\CLI\Main; use ncc\CLI\Main;
use ncc\ncc; use ncc\ncc;
use ncc\Objects\CliHelpSection;
use ncc\ThirdParty\Symfony\Process\ExecutableFinder;
class Console class Console
{ {
@ -425,4 +427,48 @@
} }
} }
} }
/**
* Prompts for a password input while hiding the user's password
*
* @param string $prompt
* @return string|null
*/
public static function passwordInput(string $prompt): ?string
{
if(!ncc::cliMode())
return null;
$executable_finder = new ExecutableFinder();
$bash_path = $executable_finder->find('bash');
if($bash_path == null)
{
self::outWarning('Unable to find bash executable, cannot hide password input');
return self::getInput($prompt);
}
$prompt = escapeshellarg($prompt);
$random = Functions::randomString(10);
$command = "$bash_path -c 'read -s -p $prompt $random && echo \$" . $random . "'";
$password = rtrim(shell_exec($command));
self::out((string)null);
return $password;
}
/**
* @param array $sections
* @return void
*/
public static function outHelpSections(array $sections): void
{
if(!ncc::cliMode())
return;
$padding = Functions::detectParametersPadding($sections);
foreach($sections as $section)
Console::out(' ' . $section->toString($padding));
}
} }

View file

@ -376,6 +376,7 @@
* @throws AccessDeniedException * @throws AccessDeniedException
* @throws FileNotFoundException * @throws FileNotFoundException
* @throws IOException * @throws IOException
* @noinspection PhpUnused
*/ */
public static function loadComposerJson(string $path): ComposerJson public static function loadComposerJson(string $path): ComposerJson
{ {
@ -430,6 +431,7 @@
* *
* @param string $property * @param string $property
* @return mixed|null * @return mixed|null
* @noinspection PhpMissingReturnTypeInspection
*/ */
public static function getConfigurationProperty(string $property) public static function getConfigurationProperty(string $property)
{ {
@ -452,4 +454,22 @@
return Parser::parse($version)->toString(); return Parser::parse($version)->toString();
} }
/**
* Returns a random string
*
* @param int $length
* @return string
*/
public static function randomString(int $length = 32): string
{
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++)
{
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString;
}
} }