From 2945c38d3cf68a0aedc81e6b8bdba0eb7ce4d285 Mon Sep 17 00:00:00 2001 From: Hugo Renard Date: Tue, 13 Dec 2022 12:06:02 +0100 Subject: [PATCH] feat: refactor indie_external to use app config --- base/Dockerfile | 2 + .../lib/AppInfo/Application.php | 43 +--- .../lib/BeforeTemplateRenderedListener.php | 31 +-- .../indie_external/lib/Settings/Personal.php | 2 +- base/apps/indie_external/lib/SitesManager.php | 242 +++++++----------- base/apps/indie_external/lib/sites.json | 60 ----- base/refresh_config.sh | 10 + 7 files changed, 123 insertions(+), 267 deletions(-) delete mode 100644 base/apps/indie_external/lib/sites.json create mode 100755 base/refresh_config.sh diff --git a/base/Dockerfile b/base/Dockerfile index 78beebf..25aad8e 100644 --- a/base/Dockerfile +++ b/base/Dockerfile @@ -12,6 +12,7 @@ RUN rm ./install.sh ./install-list ./mail-enumeration-leak.patch ./files_version FROM nextcloud:${MARKETTING_VERSION}-fpm-alpine ENV VERSION $PATCH_VERSION +ENV VISIO_URL=https://meet.liiib.re RUN apk add --no-cache patch jq COPY redis.ini /usr/local/etc/php/conf.d/ COPY opcache-recommended.ini /usr/local/etc/php/conf.d/opcache.ini @@ -26,6 +27,7 @@ COPY ./img/logo /usr/src/nextcloud/core/img/logo COPY ./img/favicon.ico /usr/src/nextcloud/core/img/favicon.ico COPY ./css/indie.scss /usr/src/nextcloud/core/css/indie.scss COPY install.sh /install.sh +COPY refresh_config.sh /refresh_config.sh RUN for app in $(cat /usr/src/nextcloud/apps/remove-list);do \ echo "removing app $app"; \ rm -R /usr/src/nextcloud/apps/$app; \ diff --git a/base/apps/indie_external/lib/AppInfo/Application.php b/base/apps/indie_external/lib/AppInfo/Application.php index 64f184f..2188532 100644 --- a/base/apps/indie_external/lib/AppInfo/Application.php +++ b/base/apps/indie_external/lib/AppInfo/Application.php @@ -26,6 +26,7 @@ use OCA\IndieExternal\Settings\Personal; use OCA\IndieExternal\SitesManager; use OCP\AppFramework\App; use OCP\IServerContainer; +use OCP\INavigationManager; use Symfony\Component\EventDispatcher\GenericEvent; class Application extends App { @@ -41,45 +42,20 @@ class Application extends App { /** @var SitesManager $sitesManager */ $sitesManager = $this->getContainer()->query(SitesManager::class); - $sites = $sitesManager->getSitesToDisplay(); - $this->registerNavigationEntries($server, $sites); - $this->registerPersonalPage($server, $sites); + $this->registerNavigationEntries($server, $sitesManager); + $this->registerPersonalPage($server, $sitesManager); } /** * @param IServerContainer $server * @param array[] $sites */ - public function registerNavigationEntries(IServerContainer $server, array $sites) { - foreach ($sites as $id => $site) { - if ($site['type'] !== SitesManager::TYPE_LINK && $site['type'] !== SitesManager::TYPE_SETTING && $site['type'] !== SitesManager::TYPE_LOGIN ) { - continue; - } - - $server->getNavigationManager()->add(function() use ($site, $server) { - $url = $server->getURLGenerator(); - - if ($site['icon'] !== '') { - $image = $url->linkToRoute('indie_external.icon.showIcon', ['icon' => $site['icon']]); - } else { - $image = $url->linkToRoute('indie_external.icon.showIcon', ['icon' => 'external.svg']); - } - - $href = $site['url']; - if (!$site['redirect']) { - $href = $url->linkToRoute('indie_external.site.showPage', ['id'=> $site['id']]); - } - - return [ - 'id' => 'indie_external_index' . $site['id'], - 'order' => 80 + $site['id'], - 'href' => $href, - 'icon' => $image, - 'type' => $site['type'], - 'name' => $site['name'], - ]; - }); + public function registerNavigationEntries(IServerContainer $server, SitesManager $sitesManager) { + $navigationManager = $this->getContainer()->query(INavigationManager::class); + $entries = $sitesManager->getNavigationEntries(); + foreach ($entries as $id => $entry) { + $navigationManager->add($entry); } } @@ -87,7 +63,8 @@ class Application extends App { * @param IServerContainer $server * @param array[] $sites */ - public function registerPersonalPage(IServerContainer $server, array $sites) { + public function registerPersonalPage(IServerContainer $server, SitesManager $sitesManager) { + $sites = $sitesManager->getSites(); foreach ($sites as $site) { if ($site['type'] === SitesManager::TYPE_QUOTA) { $server->getSettingsManager()->registerSetting('personal', Personal::class); diff --git a/base/apps/indie_external/lib/BeforeTemplateRenderedListener.php b/base/apps/indie_external/lib/BeforeTemplateRenderedListener.php index 74280d4..faeb07f 100644 --- a/base/apps/indie_external/lib/BeforeTemplateRenderedListener.php +++ b/base/apps/indie_external/lib/BeforeTemplateRenderedListener.php @@ -55,34 +55,9 @@ class BeforeTemplateRenderedListener implements IEventListener { } protected function generateNavigationLinks(): void { - $sites = $this->sitesManager->getSitesToDisplay(); - - foreach ($sites as $id => $site) { - if ($site['type'] !== SitesManager::TYPE_LINK && $site['type'] !== SitesManager::TYPE_SETTING && $site['type'] !== SitesManager::TYPE_LOGIN ) { - continue; - } - - $this->navigationManager->add(function() use ($site) { - if ($site['icon'] !== '') { - $image = $this->urlGenerator->linkToRoute('indie_external.icon.showIcon', ['icon' => $site['icon']]); - } else { - $image = $this->urlGenerator->linkToRoute('indie_external.icon.showIcon', ['icon' => 'external.svg']); - } - - $href = $site['url']; - if (!$site['redirect']) { - $href = $this->urlGenerator->linkToRoute('indie_external.site.showPage', ['id'=> $site['id']]); - } - - return [ - 'id' => 'indie_external_index' . $site['id'], - 'order' => 80 + $site['id'], - 'href' => $href, - 'icon' => $image, - 'type' => $site['type'], - 'name' => $site['name'], - ]; - }); + $entries = $this->sitesManager->getNavigationEntries(); + foreach ($entries as $id => $entry) { + $this->navigationManager->add($entry); } } } diff --git a/base/apps/indie_external/lib/Settings/Personal.php b/base/apps/indie_external/lib/Settings/Personal.php index 5eed649..19b107e 100644 --- a/base/apps/indie_external/lib/Settings/Personal.php +++ b/base/apps/indie_external/lib/Settings/Personal.php @@ -45,7 +45,7 @@ class Personal implements ISettings { * @return TemplateResponse */ public function getForm() { - $sites = $this->sitesManager->getSitesToDisplay(); + $sites = $this->sitesManager->getSites(); $quotaLink = []; foreach ($sites as $site) { diff --git a/base/apps/indie_external/lib/SitesManager.php b/base/apps/indie_external/lib/SitesManager.php index 00e8aaf..99fb421 100644 --- a/base/apps/indie_external/lib/SitesManager.php +++ b/base/apps/indie_external/lib/SitesManager.php @@ -21,24 +21,17 @@ namespace OCA\IndieExternal; -use OCA\IndieExternal\Exceptions\GroupNotFoundException; -use OCA\IndieExternal\Exceptions\IconNotFoundException; -use OCA\IndieExternal\Exceptions\InvalidDeviceException; -use OCA\IndieExternal\Exceptions\InvalidNameException; -use OCA\IndieExternal\Exceptions\InvalidTypeException; -use OCA\IndieExternal\Exceptions\InvalidURLException; -use OCA\IndieExternal\Exceptions\LanguageNotFoundException; use OCA\IndieExternal\Exceptions\SiteNotFoundException; use OCP\App\IAppManager; use OCP\Files\IAppData; -use OCP\Files\NotFoundException; -use OCP\Files\SimpleFS\ISimpleFile; use OCP\IConfig; use OCP\IGroupManager; use OCP\IRequest; use OCP\IUser; use OCP\IUserSession; use OCP\L10N\IFactory; +use OCP\INavigationManager; +use OCP\IURLGenerator; class SitesManager { @@ -53,6 +46,8 @@ class SitesManager { const DEVICE_DESKTOP = 'desktop'; const DEVICE_BROWSER = 'browser'; + const APP_NAME = 'indie_external'; + /** @var IRequest */ protected $request; @@ -74,6 +69,8 @@ class SitesManager { /** @var IAppData */ protected $appData; + /** @var IURLGenerator */ + protected $urlGenerator; public function __construct(IRequest $request, IConfig $config, @@ -81,7 +78,8 @@ class SitesManager { IGroupManager $groupManager, IUserSession $userSession, IFactory $languageFactory, - IAppData $appData) { + IAppData $appData, + IURLGenerator $urlGenerator) { $this->request = $request; $this->config = $config; $this->appManager = $appManager; @@ -89,6 +87,7 @@ class SitesManager { $this->userSession = $userSession; $this->languageFactory = $languageFactory; $this->appData = $appData; + $this->urlGenerator = $urlGenerator; } /** @@ -98,170 +97,123 @@ class SitesManager { */ public function getSiteById($id) { $sites = $this->getSites(); - - if (isset($sites[$id])) { - $site = $sites[$id]; - - $user = $this->userSession->getUser(); - $email= $user instanceof IUser ? $user->getEMailAddress() : ''; - $uid = $user instanceof IUser ? $user->getUID() : ''; - $displayName = $user instanceof IUser ? $user->getDisplayName() : ''; - $chat_url = getenv('CHAT_URL', true) ?: getenv('CHAT_URL'); - $saml_idp_url = getenv('SAML_IDP_URL', true) ?: getenv('SAML_IDP_URL'); - $saml_realm = getenv('SAML_REALM', true) ?: getenv('SAML_REALM'); - $quota_url = "/settings/users"; - - $site['url'] = str_replace(['{email}', '{uid}', '{displayname}', '{chat_url}', '{saml_idp_url}', '{saml_realm}', '{quota_url}'], [$email, $uid, $displayName, $chat_url, $saml_idp_url, $saml_realm, $quota_url], $site['url']); - - if ($site['name'] === 'Visio') { - $visio_url = getenv('VISIO_URL', true) ?: getenv('VISIO_URL'); - if ($visio_url) { - $site['url'] = $visio_url; - } + foreach ($sites as $index => $site) { + if ($id == $site["id"]) { + return $site; } - - if ($site['kind'] === 'support') { - $support_url = getenv('SUPPORT_URL', true) ?: getenv('SUPPORT_URL'); - if ($support_url) { - $site['url'] = $support_url; - } - } - - return $site; } - throw new SiteNotFoundException(); } /** * @return array[] */ - public function getSitesToDisplay() { - $sites = $this->getSites(); - $lang = $this->languageFactory->findLanguage(); - $device = $this->getDeviceFromUserAgent(); + public function getSites() { + $chat_url = $this->config->getAppValue(self::APP_NAME, "chat_url"); + $sso_url = $this->config->getAppValue(self::APP_NAME, "sso_url"); + $sso_redirect = filter_var($this->config->getAppValue(self::APP_NAME, "sso_redirect"), FILTER_VALIDATE_BOOLEAN); + $visio_url = $this->config->getAppValue(self::APP_NAME, "visio_url"); $user = $this->userSession->getUser(); + $isAdmin = false; if ($user instanceof IUser) { - $groups = $this->groupManager->getUserGroupIds($this->userSession->getUser()); - } else { - $groups = []; + $isAdmin = $this->groupManager->isAdmin($user->getUID()); } - $email= $user instanceof IUser ? $user->getEMailAddress() : ''; - $uid = $user instanceof IUser ? $user->getUID() : ''; - $displayName = $user instanceof IUser ? $user->getDisplayName() : ''; - $saml_idp_url = getenv('SAML_IDP_URL', true) ?: getenv('SAML_IDP_URL'); - $saml_realm = getenv('SAML_REALM', true) ?: getenv('SAML_REALM'); + $sites = []; - $langSites = []; - foreach ($sites as $id => $site) { - if ($site['lang'] !== '' && $site['lang'] !== $lang) { - continue; - } - - if ($site['device'] !== self::DEVICE_ALL && $site['device'] !== $device) { - continue; - } - - if (!empty($site['groups']) && empty(array_intersect($site['groups'], $groups))) { - continue; - } + if ($chat_url) { + $sites[] = [ + 'id' => 1, + 'name' => "Chat", + 'icon' => "conversation.png", + 'url' => $chat_url, + 'type' => INavigationManager::TYPE_APPS, + 'redirect' => true, + ]; + } - if ($site['name'] === 'Chat') { - $chat_url = getenv('CHAT_URL', true) ?: getenv('CHAT_URL'); - if (!$chat_url) { // if CHAT_URL is empty or false, continue the loop and skip this item - continue; - } else { - $site['url'] = str_replace(['{chat_url}'], [$chat_url], $site['url']); - } - } - - if ($site['kind'] === 'SSO') { - if (!$saml_idp_url || !$saml_realm) { - continue; - } else { - $site['url'] = str_replace(['{saml_idp_url}', '{saml_realm}'], [$saml_idp_url, $saml_realm], $site['url']); - } - } - - if ($site['name'] === 'Visio') { - $visio_url = getenv('VISIO_URL', true) ?: getenv('VISIO_URL'); - if ($visio_url !== '') { // if VISIO_URL is empty, we use the default provided in the json - if ($visio_url == 'false') { // if VISIO_URL is 'false', continue the loop and skip this item - continue; - } else { - $site['url'] = $visio_url; - } - } - } - if ($site['kind'] === 'support') { - $support_url = getenv('SUPPORT_URL', true) ?: getenv('SUPPORT_URL'); - if ($support_url) { - $site['url'] = $support_url; - } + if ($sso_url) { + if ($isAdmin) { + $sites[] = [ + 'id' => 2, + 'name' => "Admin SSO", + 'icon' => "users.png", + 'url' => $sso_url . "/console", + 'type' => INavigationManager::TYPE_SETTINGS, + 'redirect' => $sso_redirect, + ]; } + $sites[] = [ + 'id' => 3, + 'name' => "Mon compte Liiibre", + 'icon' => "compte.png", + 'url' => $sso_url . "/account", + 'type' => INavigationManager::TYPE_SETTINGS, + 'redirect' => $sso_redirect, + ]; + } - if ($site['kind'] === 'quota') { - $nextcloud_url = getenv('OVERWRITE_CLI_URL', true) ?: getenv('OVERWRITE_CLI_URL'); - if ($nextcloud_url) { - $site['url'] = "/settings/users"; - } - } - - $site['url'] = str_replace(['{email}', '{uid}', '{displayname}'], [$email, $uid, $displayName], $site['url']); - - $langSites[$id] = $site; + $sites[] = [ + 'id' => 4, + 'name' => "Centre de Documentation", + 'icon' => "lifesaver.png", + 'url' => "https://support.indie.host/help/", + 'type' => INavigationManager::TYPE_SETTINGS, + 'redirect' => true, + ]; + + if ($visio_url) { + $sites[] = [ + 'id' => 5, + 'name' => "Visio", + 'icon' => "meet.png", + 'url' => $visio_url, + 'type' => INavigationManager::TYPE_APPS, + 'redirect' => true, + ]; } - return $langSites; - } - /** - * @return array[] - */ - public function getSites() { - $jsonEncodedList = file_get_contents(__DIR__ . '/sites.json'); - $sites = json_decode($jsonEncodedList, true); - - $sites = array_map([$this, 'fillSiteArray'], $sites); + if ($isAdmin) { + $sites[] = [ + 'id' => 6, + 'name' => "Quota des comptes", + 'icon' => "quota.png", + 'url' => "/settings/users", + 'type' => INavigationManager::TYPE_SETTINGS, + 'redirect' => true, + ]; + } return $sites; } /** - * Adds default values for new attributes of sites - * @param array $site - * @return array + * @return array[] */ - protected function fillSiteArray(array $site) { - return array_merge([ - 'icon' => 'external.svg', - 'lang' => '', - 'type' => self::TYPE_LINK, - 'device' => self::DEVICE_ALL, - 'groups' => [], - 'redirect' => false, - ], - $site - ); - } + public function getNavigationEntries() { + $sites = $this->getSites(); + $entries = []; + foreach ($sites as $id => $site) { + $image = $this->urlGenerator->linkToRoute('indie_external.icon.showIcon', ['icon' => $site['icon']]); + $href = $site['url']; + if (!$site['redirect']) { + $href = $this->urlGenerator->linkToRoute('indie_external.site.showPage', ['id' => $site['id']]); + } - /** - * @return string - */ - protected function getDeviceFromUserAgent() { - if ($this->request->isUserAgent([IRequest::USER_AGENT_CLIENT_ANDROID])) { - return self::DEVICE_ANDROID; - } - if ($this->request->isUserAgent([IRequest::USER_AGENT_CLIENT_IOS])) { - return self::DEVICE_IOS; + $entries[] = [ + 'id' => 'indie_external_index' . $site['id'], + 'order' => 80 + $site['id'], + 'href' => $href, + 'icon' => $image, + 'type' => $site['type'], + 'name' => $site['name'], + ]; } - if ($this->request->isUserAgent([IRequest::USER_AGENT_CLIENT_DESKTOP])) { - return self::DEVICE_DESKTOP; - } - return self::DEVICE_BROWSER; + + return $entries; } } diff --git a/base/apps/indie_external/lib/sites.json b/base/apps/indie_external/lib/sites.json deleted file mode 100644 index 7f870e7..0000000 --- a/base/apps/indie_external/lib/sites.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "1": { - "id": 1, - "icon": "conversation.png", - "name": "Chat", - "url": "{chat_url}", - "type": "link", - "kind": "chat", - "redirect": true - }, - "2": { - "id": 2, - "icon": "users.png", - "name": "Admin SSO", - "url": "{saml_idp_url}/auth/admin/{saml_realm}/console/", - "type": "settings", - "kind": "SSO", - "groups": [ - "admin" - ] - }, - "3": { - "id": 3, - "icon": "compte.png", - "name": "Mon compte Liiibre", - "url": "{saml_idp_url}/auth/realms/{saml_realm}/account/", - "kind": "SSO", - "type": "settings" - }, - "4": { - "id": 4, - "icon": "lifesaver.png", - "name": "Centre de Documentation", - "url": "https://support.indie.host/help/", - "type": "settings", - "kind": "support", - "redirect": true - }, - "5": { - "id": 5, - "icon": "meet.png", - "name": "Visio", - "url": "https://meet.liiib.re/", - "type": "link", - "kind": "visio", - "redirect": true - }, - "6": { - "id": 6, - "icon": "quota.png", - "name": "Quota des comptes", - "url": "{quota_url}", - "type": "settings", - "kind": "quota", - "redirect": true, - "groups": [ - "admin" - ] - } -} diff --git a/base/refresh_config.sh b/base/refresh_config.sh new file mode 100755 index 0000000..6aecb9f --- /dev/null +++ b/base/refresh_config.sh @@ -0,0 +1,10 @@ +#!/bin/sh +set -eu + +/usr/local/bin/php occ config:app:set indie_external chat_url --value "${CHAT_URL}" +/usr/local/bin/php occ config:app:set indie_external visio_url --value "${VISIO_URL}" +if [ -z "$SAML_IDP_URL"]; then + /usr/local/bin/php occ config:app:delete indie_external sso_url +else + /usr/local/bin/php occ config:app:set indie_external sso_url --value "${$SAML_IDP_URL}/auth/realms/${SAML_REALM}" +fi -- GitLab