Repository: LibreTexts/ngshare (language: python)

Issue:
Running ngshare behind reverse proxy
Hello

I'm not sure how well this Project gets updated. But I think it has potential....
I wonder if someone tried to deploy this service behind a proxy such as nginx or traefik  (using URL rewrites).
Inside a Cluster it can be quite challenging to get all the services to talk to each other in the case of oauth redirects.

So far, I could not get it to work as a separate Service, which would make sense to do in our case. If someone as Inside towards this, I would be very grateful.

I submitted a pr https://github.com/LibreTexts/ngshare/pull/164 to fix at least one issue that prevented me to get it running on our cluster.
It's tested while running as a hub managed service.



Discussion / hints:

Fix patch:
diff --git a/docs/user_guide/install_jupyterhub.rst b/docs/user_guide/install_jupyterhub.rst
index 9169ba0..4c92628 100644
--- a/docs/user_guide/install_jupyterhub.rst
+++ b/docs/user_guide/install_jupyterhub.rst
@@ -30,6 +30,26 @@ You may want to check the `list of command line arguments <cmdline.html>`_ for f
 
 After you restart JupyterHub, you can verify the service is working as intended by logging into JupyterHub, clicking "Control Panel", then "Services -> ngshare". If you see the ``ngshare`` welcome page, you may proceed.
 
+Environment variables
+~~~~~~~~~~~~~~~~~~~~~
+
+Like other Services and JupyterHub itself ngsahre support some configuration via the environment. 
+
+The follwing configuration might be necessary in case the JupyterHub is running behindd a reverse proxy.
+``JUPYTERHUB_SERVICE_REDIRECT_URL`` is the URL that ``ngshare`` calles after the oauth authentication with the hub. For example: ``/my_hub_proxy_prefix/services/ngshare/```. The default values is ``/services/ngshare/```. 
+
+Example for hub-managed-services:
+.. code:: python
+
+    c.JupyterHub.services.append(
+        {
+            'name': 'ngshare',
+            'url': 'http://127.0.0.1:10101',
+            'command': ['python3', '-m', 'ngshare', '--admins', 'admin,admin2'],
+            'environment': { 'JUPYTERHUB_SERVICE_REDIRECT_URL': '/my_hub_proxy_prefix/services/ngshare/'}
+        }
+    )
+
 Installing ngshare_exchange
 ---------------------------
 
diff --git a/docs/user_guide/install_unmanaged.rst b/docs/user_guide/install_unmanaged.rst
index 28e2885..19b9c4e 100644
--- a/docs/user_guide/install_unmanaged.rst
+++ b/docs/user_guide/install_unmanaged.rst
@@ -20,6 +20,11 @@ Mocking Required Environment Variables
 
 ``JUPYTERHUB_SERVICE_URL`` is the URL that ``ngshare`` should be accessible on. For example, if ``ngshare`` has IP ``10.1.2.3`` and you want ``ngshare`` to listen on port 1234, this should be ``http://10.1.2.3:1234``. Changing this will affect ``ngshare``'s port.
 
+Additional Environment Variables for ngshare
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+The follwing variable might be necessary in case the JupyterHub is running behindd a reverse proxy.
+``JUPYTERHUB_SERVICE_REDIRECT_URL`` is the URL that ``ngshare`` calles after the oauth authentication with the hub. For example: ``/my_hub_proxy_prefix/services/ngshare/```. The default values is ``/services/ngshare/```. 
+
 Running ``ngshare``
 ^^^^^^^^^^^^^^^^^^^
 After configuring the environment variables, you may start ngshare as a service. You should also take a look at the `list of command line arguments <cmdline.html>`_ for further configuration.
diff --git a/ngshare/ngshare.py b/ngshare/ngshare.py
index 9701090..9b59700 100644
--- a/ngshare/ngshare.py
+++ b/ngshare/ngshare.py
@@ -102,7 +102,7 @@ async def get(self):
             token = await self.token_for_code(code)
             # login successful, set cookie and redirect back to home
             self.set_secure_cookie('ngshare-oauth-token', token)
-            self.redirect('/services/ngshare/')
+            self.redirect(os.environ.get("JUPYTERHUB_SERVICE_REDIRECT_URL", '/services/ngshare/')) 
         else:
             # we are the login handler,
             # begin oauth process which will come back later with an


Test patch:
diff --git a/ngshare/database/test_database.py b/ngshare/database/test_database.py
index 456097a..b7f68a8 100644
--- a/ngshare/database/test_database.py
+++ b/ngshare/database/test_database.py
@@ -10,6 +10,7 @@
 
 from sqlalchemy import create_engine
 from sqlalchemy.orm import sessionmaker
+from sqlalchemy.sql import text
 
 Session = None
 test_storage = None
@@ -31,7 +32,7 @@ def clear_db(db, storage_path):
         'submission_files_assoc_table',
         'feedback_files_assoc_table',
     ]:
-        db.execute('DELETE FROM %s' % table_name)
+        db.execute(text('DELETE FROM %s' % table_name))
     db.commit()
     if storage_path is not None:
         shutil.rmtree(storage_path, ignore_errors=True)