Skip to content

Commit

Permalink
Expose demo application policy options in config (#612)
Browse files Browse the repository at this point in the history
* DEV: make demo_applications a dictionary, keyed by app name

* DEV: extract app policy overrides from demo_applications dict

* CLN: test file tidy up

* STY: flake8 fix

* CLN: handle falsy app_license values as None in grant_access implementations

* TST: include test for default policy option override
  • Loading branch information
flongford committed Jun 29, 2022
1 parent 510430b commit d7130d3
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 17 deletions.
2 changes: 1 addition & 1 deletion jupyterhub/remoteappmanager_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
# # User accounting
#
# auto_user_creation = True
# demo_applications = ['my-demo-app']
# demo_applications = {'my-demo-app': {'allow_home': True}}
#
# # ----------------
# # Google Analytics
Expand Down
22 changes: 15 additions & 7 deletions remoteappmanager/base_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@
from remoteappmanager.services.reverse_proxy import ReverseProxy


DEFAULT_POLICY_OPTIONS = {
"app_license": None,
"allow_home": False,
"allow_view": True,
"volume": None,
"allow_startup_data": False
}


class BaseApplication(web.Application, LoggingMixin):
"""Base application provides the common infrastructure
to our tornado applications.
Expand Down Expand Up @@ -255,14 +264,13 @@ def _add_demo_apps(self, user):
for application in self.db.list_applications():
if application.image in self.file_config.demo_applications:
self.log.debug(f"Available image: {application.image}")
options = DEFAULT_POLICY_OPTIONS.copy()
options.update(
self.file_config.demo_applications[application.image])
self.db.grant_access(
application.image,
user.name,
'',
False,
True,
None,
True
app_name=application.image,
user_name=user.name,
**options
)

def _webapi_resources(self):
Expand Down
4 changes: 4 additions & 0 deletions remoteappmanager/db/orm.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,8 @@ def grant_access(self, app_name, user_name, app_license,
allow_common = False
source = target = mode = None

app_license = app_license if app_license else None

if volume is not None:
allow_common = True
source, target, mode = parse_volume_string(volume)
Expand Down Expand Up @@ -382,6 +384,8 @@ def revoke_access(self, app_name, user_name, app_license,
allow_common = False
source = target = mode = None

app_license = app_license if app_license else None

if volume is not None:
allow_common = True
source, target, mode = parse_volume_string(volume)
Expand Down
10 changes: 7 additions & 3 deletions remoteappmanager/file_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import tornado.options
from docker import tls
from traitlets import HasTraits, List, Int, Unicode, Bool, Dict
from traitlets import HasTraits, Int, Unicode, Bool, Dict

from remoteappmanager import paths
from remoteappmanager.traitlets import set_traits_from_dict
Expand Down Expand Up @@ -71,8 +71,12 @@ class FileConfig(HasTraits):
help="The google analytics tracking id"
)

#: Provide names of any default applications granted to users
demo_applications = List()
#: Provide details of default applications granted to users,
#: where keys are app names and values are dictionaries of
#: policy option overrides
demo_applications = Dict(
help="Details of default applications granted to all users."
)

#: Whether or not to automatically create user accounts upon starting
#: up the application if they do not already exist in the database
Expand Down
1 change: 1 addition & 0 deletions remoteappmanager/tests/mocking/dummy.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ def grant_access(self, app_name, user_name, app_license,
allow_home, allow_view, volume, allow_startup_data):
app = self._get_application_id_by_name(app_name)
user = self._get_user_id_by_name(user_name)
app_license = app_license if app_license else None

source, target, mode = volume.split(':')
policy = DummyDBApplicationPolicy(
Expand Down
24 changes: 20 additions & 4 deletions remoteappmanager/tests/test_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
from unittest import mock
from unittest.mock import patch

from tornado import testing
from traitlets.traitlets import TraitError

from remoteappmanager.application import Application
from remoteappmanager.db.tests import test_csv_db
from remoteappmanager.tests import utils
from remoteappmanager.tests.temp_mixin import TempMixin
from tornado import testing
from traitlets.traitlets import TraitError


class DummyDB:
Expand Down Expand Up @@ -109,7 +110,9 @@ def test_initialization_with_demo_applications(self):
"remoteappmanager.db.orm.ORMDatabase")
self.file_config.database_kwargs = {
"url": "sqlite:///"+sqlite_file_path}
self.file_config.demo_applications = ['my-demo-app']
self.file_config.demo_applications = {
'my-demo-app': {'allow_home': True}
}
self.file_config.auto_user_creation = True

app = Application(self.command_line_config,
Expand All @@ -120,7 +123,20 @@ def test_initialization_with_demo_applications(self):
self.assertIsNotNone(app.user.account)

user_apps = app.db.get_accounting_for_user(app.user.account)
self.assertEqual('my-demo-app', user_apps[0].application.image)
app_account = user_apps[0]
self.assertEqual(app_account.application.image, 'my-demo-app')
self.assertIsNone(
app_account.application_policy.app_license)
self.assertTrue(
app_account.application_policy.allow_home)
self.assertTrue(
app_account.application_policy.allow_view)
self.assertIsNone(
app_account.application_policy.volume_source)
self.assertIsNone(
app_account.application_policy.volume_target)
self.assertFalse(
app_account.application_policy.allow_startup_data)

def test_start(self):
with patch(
Expand Down
3 changes: 1 addition & 2 deletions remoteappmanager/tests/test_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ class TestUser(TestCase):

def setUp(self):
self.user = User(name='test-user',
login_service='Basic',
demo_applications=['some-image'])
login_service='Basic')

def test_init(self):
self.assertEqual('test-user', self.user.name)
Expand Down

0 comments on commit d7130d3

Please sign in to comment.