From 06834d92c48bf3e0592f03591e2f09f8c47e2acb Mon Sep 17 00:00:00 2001 From: yggverse Date: Sun, 4 Aug 2024 03:07:29 +0300 Subject: [PATCH] use shared identity driver, fix active option detection, other optimizations --- src/Entity/Browser/Container/Page/Auth.php | 134 ++++++++++++------ .../Page/Auth/Option/Identity/Name.php | 2 +- src/Model/Connection/Gemini.php | 69 +-------- src/Model/Identity/Gemini.php | 71 ++++++++++ 4 files changed, 163 insertions(+), 113 deletions(-) diff --git a/src/Entity/Browser/Container/Page/Auth.php b/src/Entity/Browser/Container/Page/Auth.php index 881739c0..76719f43 100644 --- a/src/Entity/Browser/Container/Page/Auth.php +++ b/src/Entity/Browser/Container/Page/Auth.php @@ -19,6 +19,8 @@ use \Yggverse\Yoda\Entity\Browser\Container\Page; use \Yggverse\Yoda\Model\Identity\Gemini; +use \Yggverse\Net\Address; + class Auth { // GTK @@ -161,50 +163,86 @@ class Auth // Build options list foreach ($this->_options as $id => $option) { - // Detect active identity - $option->gtk->set_active( - boolval( - $this->page->container->browser->database->auth->like( - $this->page->navbar->request->getValue(), 1 // one - ) - ) - ); - - // Append option - $content->add( - $option->gtk - ); - - // Is new and option has name entity - if (!$id && !is_null($option->name)) + // Detect option type + switch ($id) { - // Append name entry after new identity option - $content->add( - $option->name->gtk, - true, - true, - 0 - ); + // Is new cert option + case Auth\Option\Identity::ID_CRT_NEW: - // Append separator - $content->add( - new GtkSeparator( - GtkOrientation::VERTICAL - ) - ); + // Set extra margin + $option->gtk->set_margin_bottom( + $option::MARGIN + ); - // Set margin - $option->gtk->set_margin_bottom( - self::MARGIN - ); + // Append option + $content->add( + $option->gtk + ); + + // Append name entry after new identity option + $content->add( + $option->name->gtk, + true, + true, + 0 + ); + + // Append separator + $content->add( + new GtkSeparator( + GtkOrientation::VERTICAL + ) + ); + + break; + + // Is logout option + case Auth\Option\Identity::ID_LOG_OUT: + + // Set extra margin + $option->gtk->set_margin_bottom( + $option::MARGIN + ); + + // Append option + $content->add( + $option->gtk + ); + + break; + + // Is DB + default: + + // Append option + $content->add( + $option->gtk + ); + + // Detect active option match identity driver conditions + switch (true) + { + case parse_url( + $this->page->navbar->request->getValue(), + PHP_URL_SCHEME + ) == 'gemini': + + $option->gtk->set_active( + boolval( + Gemini::match( + new Address( + $this->page->navbar->request->getValue() + ), + $this->page->container->browser->database + ) + ) + ); + + break; + } } } - // Add final separator - $content->add( - new GtkLabel - ); - // Render $this->gtk->show_all(); @@ -216,7 +254,7 @@ class Auth { if ($option->gtk->get_active()) { - // Route ID + // Detect option type switch ($id) { case Auth\Option\Identity::ID_LOG_OUT: @@ -299,13 +337,19 @@ class Auth // Detect active option foreach ($this->_options as $id => $option) { - // Is new and option has name entity - if (!$id && !is_null($option->name)) + // Detect option type + switch ($id) { - // Update sensibility - $option->name->gtk->set_sensitive( - $option->gtk->get_active() - ); + case Auth\Option\Identity::ID_CRT_NEW: + + // Is name entity defined + if (!is_null($option->name)) + { + // Update sensibility + $option->name->gtk->set_sensitive( + $option->gtk->get_active() + ); + } break; } diff --git a/src/Entity/Browser/Container/Page/Auth/Option/Identity/Name.php b/src/Entity/Browser/Container/Page/Auth/Option/Identity/Name.php index da81c174..e107669e 100644 --- a/src/Entity/Browser/Container/Page/Auth/Option/Identity/Name.php +++ b/src/Entity/Browser/Container/Page/Auth/Option/Identity/Name.php @@ -47,7 +47,7 @@ class Name ); $this->gtk->set_margin_bottom( - $this::MARGIN + $this::MARGIN * 2 ); $this->gtk->show(); diff --git a/src/Model/Connection/Gemini.php b/src/Model/Connection/Gemini.php index 41043d57..91bbda0e 100644 --- a/src/Model/Connection/Gemini.php +++ b/src/Model/Connection/Gemini.php @@ -6,6 +6,7 @@ namespace Yggverse\Yoda\Model\Connection; use \Yggverse\Yoda\Model\Connection; use \Yggverse\Yoda\Model\Filesystem; +use \Yggverse\Yoda\Model\Identity\Gemini as Identity; use \Yggverse\Gemini\Client\Request; use \Yggverse\Gemini\Client\Response; @@ -36,7 +37,7 @@ class Gemini $options = $request->getOptions(); // Apply identity if available - if ($identity = $this->matchIdentity($address)) + if ($identity = Identity::match($address, $this->_connection->database)) { $crt = tmpfile(); @@ -366,72 +367,6 @@ class Gemini ); } - /** - * Return identity match request | NULL - * - * https://geminiprotocol.net/docs/protocol-specification.gmi#client-certificates - * - */ - public function matchIdentity( - Address $address, - array $identities = [] - ): ?object - { - foreach ( - // Select host records - $this->_connection->database->auth->like( - sprintf( - '%s%%', - $address->get( - true, - true, - true, - true, - true, - false, - false, - false - ) - ) - ) as $auth - ) { - // Parse result address - $request = new Address( - $auth->request - ); - - // Filter results match current path prefix - if (str_starts_with($address->getPath(), $request->getPath())) - { - $identities[ - $auth->identity - ] = $auth->request; - } - } - - // Results found - if ($identities) - { - uasort( // max-level - $identities, - function ($a, $b) - { - return mb_strlen($b) <=> mb_strlen($a); - } - ); - - return $this->_connection->database->identity->get( - intval( - array_key_first( - $identities - ) - ) - ); - } - - return null; - } - public static function getMimeByMeta( ?string $meta = null ): ?string diff --git a/src/Model/Identity/Gemini.php b/src/Model/Identity/Gemini.php index 430f5228..a5377d08 100644 --- a/src/Model/Identity/Gemini.php +++ b/src/Model/Identity/Gemini.php @@ -8,6 +8,10 @@ use \Exception; use \OpenSSLAsymmetricKey; use \OpenSSLCertificate; +use \Yggverse\Net\Address; + +use \Yggverse\Yoda\Model\Database; + class Gemini extends \Yggverse\Yoda\Abstract\Model\Identity { // Init defaults @@ -79,4 +83,71 @@ class Gemini extends \Yggverse\Yoda\Abstract\Model\Identity throw new Exception; } + + /** + * Return identity match Address | NULL + * + * https://geminiprotocol.net/docs/protocol-specification.gmi#client-certificates + * + */ + public static function match( + Address $address, + Database $database, + array $identities = [] + ): ?object + { + foreach ( + // Select host records + $database->auth->like( + sprintf( + '%s%%', + $address->get( + true, + true, + true, + true, + true, + false, + false, + false + ) + ) + ) as $auth + ) { + // Parse result address + $request = new Address( + $auth->request + ); + + // Filter results match current path prefix + if (str_starts_with($address->getPath(), $request->getPath())) + { + $identities[ + $auth->identity + ] = $auth->request; + } + } + + // Results found + if ($identities) + { + uasort( // max-level + $identities, + function ($a, $b) + { + return mb_strlen($b) <=> mb_strlen($a); + } + ); + + return $database->identity->get( + intval( + array_key_first( + $identities + ) + ) + ); + } + + return null; + } } \ No newline at end of file