From 01a23c83147ddb5c44f89a69597422c31b152f0b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Agneray?= <francois.agneray@lam.fr>
Date: Fri, 27 Aug 2021 12:03:20 +0200
Subject: [PATCH] Client config is now provided by server

---
 client/src/app/app-init.ts                  |  5 +-
 client/src/assets/app.config.json           | 10 ----
 client/src/environments/environment.prod.ts |  3 +-
 client/src/environments/environment.ts      |  3 +-
 docker-compose.yml                          |  5 ++
 server/app/dependencies.php                 |  4 ++
 server/app/routes.php                       |  1 +
 server/app/settings.php                     |  8 ++-
 server/src/Action/ClientSettingsAction.php  | 61 +++++++++++++++++++++
 9 files changed, 86 insertions(+), 14 deletions(-)
 delete mode 100644 client/src/assets/app.config.json
 create mode 100644 server/src/Action/ClientSettingsAction.php

diff --git a/client/src/app/app-init.ts b/client/src/app/app-init.ts
index b3dc0426..6b9241ee 100644
--- a/client/src/app/app-init.ts
+++ b/client/src/app/app-init.ts
@@ -7,12 +7,15 @@ import { Store } from '@ngrx/store';
 import { AppConfigService } from './app-config.service';
 import { initializeKeycloak } from 'src/app/auth/init.keycloak';
 
+import { environment } from 'src/environments/environment';
+
 function appInit(http: HttpClient, appConfigService: AppConfigService, keycloak: KeycloakService, store: Store<{ }>) {
     return () => {
-        return http.get('/assets/app.config.json')
+        return http.get(`${environment.apiUrl}/client-settings`)
             .toPromise()
             .then(data => {
                 Object.assign(appConfigService, data);
+                appConfigService.apiUrl = environment.apiUrl;
                 return appConfigService;
             })
             .then(appConfigService => {
diff --git a/client/src/assets/app.config.json b/client/src/assets/app.config.json
deleted file mode 100644
index 69f72dd7..00000000
--- a/client/src/assets/app.config.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-    "apiUrl": "http://localhost:8080",
-    "servicesUrl": "http://localhost:5000",
-    "baseHref": "/",
-    "authenticationEnabled": false,
-    "ssoAuthUrl": "http://localhost:8180/auth",
-    "ssoRealm": "anis",
-    "ssoClientId": "anis-client",
-    "adminRole": "anis_admin"
-}
\ No newline at end of file
diff --git a/client/src/environments/environment.prod.ts b/client/src/environments/environment.prod.ts
index 5d083316..5506fedd 100644
--- a/client/src/environments/environment.prod.ts
+++ b/client/src/environments/environment.prod.ts
@@ -1,3 +1,4 @@
 export const environment = {
-    production: true
+    production: true,
+    apiUrl: "/server"
 };
diff --git a/client/src/environments/environment.ts b/client/src/environments/environment.ts
index 458476a4..0a202e32 100644
--- a/client/src/environments/environment.ts
+++ b/client/src/environments/environment.ts
@@ -3,7 +3,8 @@
 // The list of file replacements can be found in `angular.json`.
 
 export const environment = {
-    production: false
+    production: false,
+    apiUrl: "http://localhost:8080"
 };
 
 /*
diff --git a/docker-compose.yml b/docker-compose.yml
index bc9bd7b0..ee412b76 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -29,6 +29,11 @@ services:
             LOGGER_NAME: "anis-metamodel"
             LOGGER_PATH: "php://stderr"
             LOGGER_LEVEL: "debug"
+            SERVICES_URL: "http://localhost:5000"
+            BASE_HREF: "/"
+            SSO_AUTH_URL: "http://localhost:8180/auth"
+            SSO_REALM: "anis"
+            SSO_CLIENT_ID: "anis-client"
             TOKEN_ENABLED: 0
             TOKEN_PUBLIC_KEY_FILE: /mnt/public_key
             TOKEN_ADMIN_ROLE: anis_admin
diff --git a/server/app/dependencies.php b/server/app/dependencies.php
index 654451c8..2ba1d168 100644
--- a/server/app/dependencies.php
+++ b/server/app/dependencies.php
@@ -56,6 +56,10 @@ $container->set('App\Action\RootAction', function () {
     return new App\Action\RootAction();
 });
 
+$container->set('App\Action\ClientSettingsAction', function (ContainerInterface $c) {
+    return new App\Action\ClientSettingsAction($c->get(SETTINGS));
+});
+
 $container->set('App\Action\SelectListAction', function (ContainerInterface $c) {
     return new App\Action\SelectListAction($c->get('em'));
 });
diff --git a/server/app/routes.php b/server/app/routes.php
index 0c8d278c..42b9479b 100644
--- a/server/app/routes.php
+++ b/server/app/routes.php
@@ -13,6 +13,7 @@ declare(strict_types=1);
 use Slim\Routing\RouteCollectorProxy;
 
 $app->get('/', App\Action\RootAction::class);
+$app->get('/client-settings', App\Action\ClientSettingsAction::class);
 
 $app->group('', function (RouteCollectorProxy $group) {
     $group->map([OPTIONS, GET, POST], '/select', App\Action\SelectListAction::class);
diff --git a/server/app/settings.php b/server/app/settings.php
index a37c7557..f018b567 100644
--- a/server/app/settings.php
+++ b/server/app/settings.php
@@ -31,8 +31,14 @@ return [
         'path' => getenv('LOGGER_PATH'),
         'level' => getenv('LOGGER_LEVEL')
     ],
+    'services_url' => getenv('SERVICES_URL'),
+    'base_href' => getenv('BASE_HREF'),
+    'sso' => [
+        'auth_url' => getenv('SSO_AUTH_URL'),
+        'realm' => getenv('SSO_REALM'),
+        'client_id' => getenv('SSO_CLIENT_ID')
+    ],
     'token' => [
-        //'issuer' => getenv('TOKEN_ISSUER'),
         'enabled' => getenv('TOKEN_ENABLED'),
         'public_key_file' => getenv('TOKEN_PUBLIC_KEY_FILE'),
         'admin_role' => getenv('TOKEN_ADMIN_ROLE')
diff --git a/server/src/Action/ClientSettingsAction.php b/server/src/Action/ClientSettingsAction.php
new file mode 100644
index 00000000..1018ac39
--- /dev/null
+++ b/server/src/Action/ClientSettingsAction.php
@@ -0,0 +1,61 @@
+<?php
+
+/*
+ * This file is part of Anis Server.
+ *
+ * (c) Laboratoire d'Astrophysique de Marseille / CNRS
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+declare(strict_types=1);
+
+namespace App\Action;
+
+use Psr\Http\Message\ResponseInterface as Response;
+use Psr\Http\Message\ServerRequestInterface as Request;
+
+/**
+ * Client settings action
+ *
+ * @author François Agneray <francois.agneray@lam.fr>
+ * @package App\Action
+ */
+final class ClientSettingsAction
+{
+    /**
+     * The ANIS settings array
+     *
+     * @var array
+     */
+    private $settings;
+
+    public function __construct($settings)
+    {
+        $this->settings = $settings;
+    }
+
+    /**
+     * This action indicates that the service is responding
+     *
+     * @param  ServerRequestInterface $request  PSR-7 This object represents the HTTP request
+     * @param  ResponseInterface      $response PSR-7 This object represents the HTTP response
+     * @param  string[]               $args     This table contains information transmitted in the URL (see routes.php)
+     *
+     * @return ResponseInterface
+     */
+    public function __invoke(Request $request, Response $response, array $args): Response
+    {
+        $payload = json_encode(array(
+            'servicesUrl' => $this->settings['services_url'],
+            'baseHref' => $this->settings['base_href'],
+            'authenticationEnabled' => boolval($this->settings['token']['enabled']),
+            'ssoAuthUrl' => $this->settings['sso']['auth_url'],
+            'ssoRealm' => $this->settings['sso']['realm'],
+            'ssoClientId' => $this->settings['sso']['client_id'],
+            'adminRole' => $this->settings['token']['admin_role']
+        ));
+        $response->getBody()->write($payload);
+        return $response;
+    }
+}
-- 
GitLab