From f94c683ef751317adc37328a67ffa514dab3c76e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20Ivan=C4=8Di=C4=87?= Date: Wed, 13 Nov 2024 16:56:04 +0100 Subject: [PATCH] WIP move to SSP UI --- hooks/hook_adminmenu.php | 2 +- public/assets/css/src/default.css | 71 +++++++++++++++++++++++ routing/routes/routes.php | 10 ++++ routing/services/services.yml | 3 + src/Admin/Authorization.php | 40 +++++++++++++ src/Admin/Menu.php | 52 +++++++++++++++++ src/Admin/Menu/Item.php | 30 ++++++++++ src/Bridges/SspBridge/Utils.php | 7 +++ src/Codebooks/RoutesEnum.php | 4 ++ src/Controller/AdminController.php | 31 ++++++++++ src/Exceptions/AuthorizationException.php | 11 ++++ src/{ => Exceptions}/OidcException.php | 2 +- src/Factories/CacheFactory.php | 8 +-- src/Utils/ClassInstanceBuilder.php | 4 +- templates/base.twig | 35 +++++++++++ templates/config/overview.twig | 11 ++++ templates/includes/menu.twig | 13 +++++ 17 files changed, 326 insertions(+), 8 deletions(-) create mode 100644 public/assets/css/src/default.css create mode 100644 src/Admin/Authorization.php create mode 100644 src/Admin/Menu.php create mode 100644 src/Admin/Menu/Item.php create mode 100644 src/Controller/AdminController.php create mode 100644 src/Exceptions/AuthorizationException.php rename src/{ => Exceptions}/OidcException.php (63%) create mode 100644 templates/base.twig create mode 100644 templates/config/overview.twig create mode 100644 templates/includes/menu.twig diff --git a/hooks/hook_adminmenu.php b/hooks/hook_adminmenu.php index 6be1afc3..0d5f0636 100644 --- a/hooks/hook_adminmenu.php +++ b/hooks/hook_adminmenu.php @@ -20,7 +20,7 @@ function oidc_hook_adminmenu(Template &$template): void $oidcMenuEntry = [ ModuleConfig::MODULE_NAME => [ - 'url' => $moduleConfig->getModuleUrl(RoutesEnum::Configuration->value), + 'url' => $moduleConfig->getModuleUrl(RoutesEnum::AdminConfigOverview->value), 'name' => Translate::noop('OIDC'), ], ]; diff --git a/public/assets/css/src/default.css b/public/assets/css/src/default.css new file mode 100644 index 00000000..669b5670 --- /dev/null +++ b/public/assets/css/src/default.css @@ -0,0 +1,71 @@ +.wrap { + max-width: 1300px; +} + +h2 { + margin: 0.3em; +} + +h3 { + margin-bottom: 0.5em; + font-size: 1.2em; + font-weight: 600; + color: #1c1c1c; +} + +h4 { + margin: 0.4em 0; + font-size: 1.0em; + font-weight: 600; + color: #1c1c1c; +} + +/* Container to hold menu and content */ +.oidc-container { + display: flex; + max-width: inherit; + margin: 0 auto; +} + +/* Style for the left menu */ +.menu { + min-width: 200px; + /*background-color: #f4f4f4;*/ + /*border-right: solid 1px #bbb;*/ + width: auto; +} + +/* Style for the menu items */ +.menu ul { + list-style-type: none; + padding: 0; +} + +.menu ul li { + padding: 0.25rem; +} + +.menu ul li a { + text-decoration: none; + color: #333; + display: block; + padding: 0.5rem; +} + +.menu ul li a:hover { + background-color: #ddd; + padding: 0.5rem; +} + +.menu ul li a.active { + background-color: #eeeeee; + padding: 0.5rem; +} + +/* Style for the content area */ +.content { + flex-grow: 1; + padding: 20px; + max-width: inherit; + background-color: #fff; +} diff --git a/routing/routes/routes.php b/routing/routes/routes.php index 0e84a055..113f6286 100644 --- a/routing/routes/routes.php +++ b/routing/routes/routes.php @@ -8,6 +8,7 @@ use SimpleSAML\Module\oidc\Codebooks\RoutesEnum; use SimpleSAML\Module\oidc\Controller\AccessTokenController; +use SimpleSAML\Module\oidc\Controller\AdminController; use SimpleSAML\Module\oidc\Controller\AuthorizationController; use SimpleSAML\Module\oidc\Controller\ConfigurationDiscoveryController; use SimpleSAML\Module\oidc\Controller\EndSessionController; @@ -19,6 +20,15 @@ /** @psalm-suppress InvalidArgument */ return function (RoutingConfigurator $routes): void { + /** + * Admin area routes. + */ + $routes->add(RoutesEnum::AdminConfigOverview->name, RoutesEnum::AdminConfigOverview->value) + ->controller([AdminController::class, 'configOverview']); + + /** + * OpenID Connect Discovery routes. + */ $routes->add(RoutesEnum::Configuration->name, RoutesEnum::Configuration->value) ->controller(ConfigurationDiscoveryController::class); diff --git a/routing/services/services.yml b/routing/services/services.yml index 0b4ea060..f3c093c3 100644 --- a/routing/services/services.yml +++ b/routing/services/services.yml @@ -29,6 +29,9 @@ services: SimpleSAML\Module\oidc\Factories\: resource: '../../src/Factories/*' + SimpleSAML\Module\oidc\Admin\: + resource: '../../src/Admin/*' + SimpleSAML\Module\oidc\Stores\: resource: '../../src/Stores/*' diff --git a/src/Admin/Authorization.php b/src/Admin/Authorization.php new file mode 100644 index 00000000..dea36248 --- /dev/null +++ b/src/Admin/Authorization.php @@ -0,0 +1,40 @@ +sspBridge->utils()->auth()->requireAdmin(); + } catch (Exception $exception) { + throw new AuthorizationException( + Translate::noop('Unable to initiate SimpleSAMLphp admin authentication.'), + $exception->getCode(), + $exception, + ); + } + } + + if (! $this->sspBridge->utils()->auth()->isAdmin()) { + throw new AuthorizationException(Translate::noop('SimpleSAMLphp admin access required.')); + } + } +} diff --git a/src/Admin/Menu.php b/src/Admin/Menu.php new file mode 100644 index 00000000..0c5e15a6 --- /dev/null +++ b/src/Admin/Menu.php @@ -0,0 +1,52 @@ + + */ + protected array $items = []; + + protected ?string $activeHrefPath = null; + + public function __construct(Item ...$items) + { + array_push($this->items, ...$items); + } + + public function addItem(Item $menuItem, int $offset = null): void + { + $offset ??= count($this->items); + + array_splice($this->items, $offset, 0, [$menuItem]); + } + + public function getItems(): array + { + return $this->items; + } + + public function setActiveHrefPath(?string $value): void + { + $this->activeHrefPath = $value; + } + + public function getActiveHrefPath(): ?string + { + return $this->activeHrefPath; + } + + /** + * Item factory method for easy injection in tests. + */ + public function buildItem(string $hrefPath, string $label, ?string $iconAssetPath = null): Item + { + return new Item($hrefPath, $label, $iconAssetPath); + } +} diff --git a/src/Admin/Menu/Item.php b/src/Admin/Menu/Item.php new file mode 100644 index 00000000..7ce311b6 --- /dev/null +++ b/src/Admin/Menu/Item.php @@ -0,0 +1,30 @@ +hrefPath; + } + + public function getLabel(): string + { + return $this->label; + } + + public function getIconAssetPath(): ?string + { + return $this->iconAssetPath; + } +} diff --git a/src/Bridges/SspBridge/Utils.php b/src/Bridges/SspBridge/Utils.php index 12d0c70f..7b7a3705 100644 --- a/src/Bridges/SspBridge/Utils.php +++ b/src/Bridges/SspBridge/Utils.php @@ -4,6 +4,7 @@ namespace SimpleSAML\Module\oidc\Bridges\SspBridge; +use SimpleSAML\Utils\Auth; use SimpleSAML\Utils\Config; use SimpleSAML\Utils\HTTP; use SimpleSAML\Utils\Random; @@ -13,6 +14,7 @@ class Utils protected static ?Config $config = null; protected static ?HTTP $http = null; protected static ?Random $random = null; + protected static ?Auth $auth = null; public function config(): Config { @@ -28,4 +30,9 @@ public function random(): Random { return self::$random ??= new Random(); } + + public function auth(): Auth + { + return self::$auth ??= new Auth(); + } } diff --git a/src/Codebooks/RoutesEnum.php b/src/Codebooks/RoutesEnum.php index ff875c89..b5b31e3b 100644 --- a/src/Codebooks/RoutesEnum.php +++ b/src/Codebooks/RoutesEnum.php @@ -6,6 +6,10 @@ enum RoutesEnum: string { + // Admin area + case AdminConfigOverview = 'admin/config-overview'; + + // Protocols case Authorization = 'authorization'; case Configuration = '.well-known/openid-configuration'; case FederationConfiguration = '.well-known/openid-federation'; diff --git a/src/Controller/AdminController.php b/src/Controller/AdminController.php new file mode 100644 index 00000000..4def7e1f --- /dev/null +++ b/src/Controller/AdminController.php @@ -0,0 +1,31 @@ +authorization->requireSspAdmin(true); + } + + public function configOverview(): Response + { + return $this->templateFactory->render( + 'oidc:config/overview.twig', + [ + 'moduleConfig' => $this->moduleConfig, + ], + ); + } +} diff --git a/src/Exceptions/AuthorizationException.php b/src/Exceptions/AuthorizationException.php new file mode 100644 index 00000000..a5b17c4a --- /dev/null +++ b/src/Exceptions/AuthorizationException.php @@ -0,0 +1,11 @@ + +{% endblock %} + +{% block content %} + +

{{ moduleName }}

+ +
+ + {% if showMenu %} + {% include '@oidc/includes/menu.twig' %} + {% endif %} + +
+

{{ subPageTitle }}

+ +{# TODO mivanci status messages#} + + {% block oidcContent %}{% endblock %} +
+
+ +{% endblock content -%} + +{% block postload %}{% endblock postload %} + +{% block oidcPostload %}{% endblock %} diff --git a/templates/config/overview.twig b/templates/config/overview.twig new file mode 100644 index 00000000..eb462d4e --- /dev/null +++ b/templates/config/overview.twig @@ -0,0 +1,11 @@ +{% set subPageTitle = 'Config Overview'|trans %} + +{% extends "@oidc/base.twig" %} + +{% block oidcContent %} + +

{{ 'OIDC module config overview'|trans }}

+ +

{{ 'Migrations'|trans }}

+ +{% endblock oidcContent -%} diff --git a/templates/includes/menu.twig b/templates/includes/menu.twig new file mode 100644 index 00000000..e397c350 --- /dev/null +++ b/templates/includes/menu.twig @@ -0,0 +1,13 @@ +{% if menu|default %} + +{% endif %} \ No newline at end of file