Added stuff for vault manager blah blah blah

This commit is contained in:
Netkas 2022-06-05 18:38:28 -04:00
parent f86cfc64c3
commit cbdbe46b41
5 changed files with 261 additions and 1 deletions

View file

@ -5,9 +5,11 @@
use ncc\Exceptions\AccessDeniedException; use ncc\Exceptions\AccessDeniedException;
use ncc\Exceptions\DirectoryNotFoundException; use ncc\Exceptions\DirectoryNotFoundException;
use ncc\Exceptions\FileNotFoundException; use ncc\Exceptions\FileNotFoundException;
use ncc\Exceptions\InvalidCredentialsEntryException;
use ncc\Exceptions\InvalidProjectConfigurationException; use ncc\Exceptions\InvalidProjectConfigurationException;
use ncc\Exceptions\InvalidScopeException; use ncc\Exceptions\InvalidScopeException;
use ncc\Exceptions\MalformedJsonException; use ncc\Exceptions\MalformedJsonException;
use ncc\Exceptions\RuntimeException;
/** /**
* @author Zi Xing Narrakas * @author Zi Xing Narrakas
@ -45,6 +47,13 @@
*/ */
const MalformedJsonException = -1705; const MalformedJsonException = -1705;
/**
* @see RuntimeException
*/
const RuntimeException = -1706; const RuntimeException = -1706;
/**
* @see InvalidCredentialsEntryException
*/
const InvalidCredentialsEntryException = -1707;
} }

View file

@ -0,0 +1,12 @@
<?php
namespace ncc\Abstracts;
abstract class Versions
{
/**
* The current version of the credentials store file format
*/
const CredentialsStoreVersion = '1.0.0';
}

View file

@ -0,0 +1,19 @@
<?php
namespace ncc\Exceptions;
use Exception;
use ncc\Abstracts\ExceptionCodes;
use Throwable;
class InvalidCredentialsEntryException extends Exception
{
/**
* @param string $message
* @param Throwable|null $previous
*/
public function __construct(string $message = "", ?Throwable $previous = null)
{
parent::__construct($message, ExceptionCodes::InvalidCredentialsEntryException, $previous);
}
}

View file

@ -0,0 +1,158 @@
<?php
/** @noinspection PhpMissingFieldTypeInspection */
namespace ncc\Managers;
use ncc\Abstracts\Scopes;
use ncc\Abstracts\Versions;
use ncc\Exceptions\AccessDeniedException;
use ncc\Exceptions\InvalidCredentialsEntryException;
use ncc\Exceptions\RuntimeException;
use ncc\Objects\Vault;
use ncc\Utilities\PathFinder;
use ncc\Utilities\Resolver;
use ncc\ZiProto\ZiProto;
class CredentialManager
{
/**
* @var null
*/
private $CredentialsPath;
/**
* Public Constructor
*/
public function __construct()
{
$this->CredentialsPath = PathFinder::getDataPath(Scopes::System) . DIRECTORY_SEPARATOR . 'credentials.store';
}
/**
* Determines if CredentialManager has correct access to manage credentials on the system
*
* @return bool
*/
public function checkAccess(): bool
{
$ResolvedScope = Resolver::resolveScope();
if($ResolvedScope !== Scopes::System)
{
return False;
}
return True;
}
/**
* Constructs the store file if it doesn't exist on the system (First initialization)
*
* @return void
* @throws AccessDeniedException
* @throws RuntimeException
*/
public function constructStore(): void
{
// Do not continue the function if the file already exists, if the file is damaged a seperate function
// is to be executed to fix the damaged file.
if(file_exists($this->CredentialsPath))
return;
if(!$this->checkAccess())
{
throw new AccessDeniedException('Cannot construct credentials store without system permissions');
}
$VaultObject = new Vault();
$VaultObject->Version = Versions::CredentialsStoreVersion;
// TODO: Set proper permissions for root access only for the file
if(!@file_put_contents($this->CredentialsPath, ZiProto::encode($VaultObject->toArray())))
{
throw new RuntimeException('Cannot create file \'' . $this->CredentialsPath . '\'');
}
}
/**
* Returns the vault object from the credentials store file.
*
* @return Vault
* @throws AccessDeniedException
* @throws RuntimeException
*/
public function getVault(): Vault
{
$this->constructStore();
if(!$this->checkAccess())
{
throw new AccessDeniedException('Cannot read credentials store without system permissions');
}
try
{
$Vault = ZiProto::decode(file_get_contents($this->CredentialsPath));
}
catch(\Exception $e)
{
// TODO: Implement error-correction for corrupted credentials store.
throw new RuntimeException($e->getMessage(), $e);
}
$Vault = Vault::fromArray($Vault);
return $Vault;
}
/**
* Saves the vault object to the credentials store
*
* @param Vault $vault
* @return void
* @throws AccessDeniedException
*/
public function saveVault(Vault $vault)
{
if(!$this->checkAccess())
{
throw new AccessDeniedException('Cannot write to credentials store without system permissions');
}
file_put_contents($this->CredentialsPath, ZiProto::encode($vault->toArray()));
}
/**
* Registers an entry to the credentials store file
*
* @param Vault\Entry $entry
* @return void
* @throws AccessDeniedException
* @throws InvalidCredentialsEntryException
* @throws RuntimeException
*/
public function registerEntry(Vault\Entry $entry)
{
if(!preg_match('/^[\w-]+$/', $entry->Alias))
{
throw new InvalidCredentialsEntryException('The property \'Alias\' must be alphanumeric (Regex error)');
}
// TODO: Implement more validation checks for the rest of the entry properties.
// TODO: Implement encryption for entries that require encryption (For securing passwords and data)
$Vault = $this->getVault();
$Vault->Entries[] = $entry;
$this->saveVault($Vault);
}
/**
* @return null
*/
public function getCredentialsPath()
{
return $this->CredentialsPath;
}
}

View file

@ -2,6 +2,7 @@
namespace ncc\Objects; namespace ncc\Objects;
use ncc\Objects\Vault\DefaultEntry;
use ncc\Objects\Vault\Entry; use ncc\Objects\Vault\Entry;
class Vault class Vault
@ -14,7 +15,68 @@
public $Version; public $Version;
/** /**
* The vault's stored credential entries
*
* @var Entry[] * @var Entry[]
*/ */
public $Entries; public $Entries;
/**
*
*
* @var DefaultEntry[]
*/
public $DefaultEntries;
/**
* Public Constructor
*/
public function __construct()
{
$this->Entries = [];
}
/**
* Returns an array representation of the object
*
* @return array
*/
public function toArray(): array
{
$Entries = [];
foreach($this->Entries as $entry)
{
$Entries[] = $entry->toArray();
}
return [
'version' => $this->Version,
'entries' => $Entries
];
}
/**
* Constructs an object from an array representation
*
* @param array $data
* @return Vault
*/
public static function fromArray(array $data): Vault
{
$VaultObject = new Vault();
if(isset($data['version']))
$VaultObject->Version = $data['version'];
if(isset($data['entries']))
{
foreach($data['entries'] as $entry)
{
$VaultObject->Entries[] = Entry::fromArray($entry);
}
}
return $VaultObject;
}
} }