From cbdbe46b41b66b039fcdcd64ec75c3fca1b0ed68 Mon Sep 17 00:00:00 2001 From: Netkas Date: Sun, 5 Jun 2022 18:38:28 -0400 Subject: [PATCH] Added stuff for vault manager blah blah blah --- src/ncc/Abstracts/ExceptionCodes.php | 11 +- src/ncc/Abstracts/Versions.php | 12 ++ .../InvalidCredentialsEntryException.php | 19 +++ src/ncc/Managers/CredentialManager.php | 158 ++++++++++++++++++ src/ncc/Objects/Vault.php | 62 +++++++ 5 files changed, 261 insertions(+), 1 deletion(-) create mode 100644 src/ncc/Abstracts/Versions.php create mode 100644 src/ncc/Exceptions/InvalidCredentialsEntryException.php create mode 100644 src/ncc/Managers/CredentialManager.php diff --git a/src/ncc/Abstracts/ExceptionCodes.php b/src/ncc/Abstracts/ExceptionCodes.php index a142b61..11e305a 100644 --- a/src/ncc/Abstracts/ExceptionCodes.php +++ b/src/ncc/Abstracts/ExceptionCodes.php @@ -5,9 +5,11 @@ use ncc\Exceptions\AccessDeniedException; use ncc\Exceptions\DirectoryNotFoundException; use ncc\Exceptions\FileNotFoundException; + use ncc\Exceptions\InvalidCredentialsEntryException; use ncc\Exceptions\InvalidProjectConfigurationException; use ncc\Exceptions\InvalidScopeException; use ncc\Exceptions\MalformedJsonException; + use ncc\Exceptions\RuntimeException; /** * @author Zi Xing Narrakas @@ -45,6 +47,13 @@ */ const MalformedJsonException = -1705; - + /** + * @see RuntimeException + */ const RuntimeException = -1706; + + /** + * @see InvalidCredentialsEntryException + */ + const InvalidCredentialsEntryException = -1707; } \ No newline at end of file diff --git a/src/ncc/Abstracts/Versions.php b/src/ncc/Abstracts/Versions.php new file mode 100644 index 0000000..f579c66 --- /dev/null +++ b/src/ncc/Abstracts/Versions.php @@ -0,0 +1,12 @@ +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; + } + } \ No newline at end of file diff --git a/src/ncc/Objects/Vault.php b/src/ncc/Objects/Vault.php index 83b11a3..8a60105 100644 --- a/src/ncc/Objects/Vault.php +++ b/src/ncc/Objects/Vault.php @@ -2,6 +2,7 @@ namespace ncc\Objects; + use ncc\Objects\Vault\DefaultEntry; use ncc\Objects\Vault\Entry; class Vault @@ -14,7 +15,68 @@ public $Version; /** + * The vault's stored credential entries + * * @var Entry[] */ 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; + } } \ No newline at end of file