Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix User demo application assignment #569

Merged
merged 13 commits into from
Sep 7, 2021
Merged
7 changes: 6 additions & 1 deletion jupyterhub/remoteappmanager_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,12 @@
# database_class = "remoteappmanager.db.orm.ORMDatabase"
# database_kwargs = {
# "url": "sqlite:///"+os.path.abspath('./remoteappmanager.db')}

#
# # User accounting
#
# auto_user_creation = True
# demo_applications = ['my-demo-app']
#
# # ----------------
# # Google Analytics
# # ----------------
Expand Down
28 changes: 23 additions & 5 deletions remoteappmanager/base_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,20 @@ def _user_default(self):
user_name = self.command_line_config.user
login_service = self.command_line_config.login_service
user = User(name=user_name, login_service=login_service)
user.account = self.db.get_user(user_name=user_name)

# Handle User accounting
if self.db.get_user(user_name=user.name) is None:
self.log.info(
"User account not found for {}:".format(user.name))
if self.file_config.auto_user_creation:
self.log.info(
"Creating new User account for {}:".format(user.name))
self.db.create_user(user.name)
else:
self.log.info("User account found for {}:".format(user.name))
user.account = self.db.get_user(user_name=user.name)

# Add any demo apps to registry
self.log.info("Adding demo apps to User registry:")
self._add_demo_apps(user)

Expand Down Expand Up @@ -168,20 +180,26 @@ def start(self):
# Private
def _add_demo_apps(self, user):
"""Grant access to any demo applications provided for user"""
if user.account is None:
self.log.debug("No user account available")
return

if user.demo_applications:
if not self.file_config.demo_applications:
self.log.debug("No demo applications available")
return

# Add all demo applications already registered
for application in self.db.list_applications():
if application.image in user.demo_applications:
self.log.info(application.image)
if application.image in self.file_config.demo_applications:
self.log.debug(f"Avaliable image: {application.image}")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a small typo here.

self.db.grant_access(
application.image,
user.name,
'',
False,
True,
None
None,
True
)

def _webapi_resources(self):
Expand Down
9 changes: 8 additions & 1 deletion 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, Int, Unicode, Bool, Dict
from traitlets import HasTraits, List, Int, Unicode, Bool, Dict

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

#: Provide names of any default applications granted to users
demo_applications = List()

#: Whether or not to automatically create user accounts upon starting
#: up the application if they do not already exist in the database
auto_user_creation = Bool(False)

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Sets the default of the docker configuration options from the
Expand Down
31 changes: 30 additions & 1 deletion remoteappmanager/tests/test_application.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ def test_initialization_with_sqlite_db(self):
self.assertIsNotNone(app.container_manager)
self.assertIsNotNone(app.hub)
self.assertEqual(app.user.name, "johndoe")
self.assertEqual(app.user.account, None)
self.assertEqual(app.user.login_service, "")
self.assertIsNone(app.user.account)

def test_error_default_value_with_unimportable_accounting(self):
self.file_config.database_class = "not.importable.Class"
Expand Down Expand Up @@ -93,6 +94,34 @@ def test_initialization(self):
self.assertEqual(app.user.name, "johndoe")
self.assertIsInstance(app.user.account, test_csv_db.CSVUser)

def test_initialization_with_demo_applications(self):
# Initialise database
sqlite_file_path = os.path.join(self.tempdir, "sqlite.db")
utils.init_sqlite_db(sqlite_file_path)

# Add demo app to database using remoteappmanager API
from remoteappmanager.db.orm import ORMDatabase
test_db = ORMDatabase("sqlite:///"+sqlite_file_path)
test_db.create_application('my-demo-app')
del test_db

self.file_config.database_class = (
"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.auto_user_creation = True

app = Application(self.command_line_config,
self.file_config,
self.environment_config)

self.assertEqual(app.user.name, "johndoe")
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)

def test_start(self):
with patch(
"remoteappmanager.application.Application.listen"
Expand Down
16 changes: 7 additions & 9 deletions remoteappmanager/tests/test_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@
class TestUser(TestCase):

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

self.user = User()

def test_demo_applications(self):

self.assertListEqual([], self.user.demo_applications)
self.assertListEqual(
[],
self.user.demo_applications
)
def test_init(self):
self.assertEqual('test-user', self.user.name)
self.assertIsNone(self.user.account)
self.assertEqual('Basic', self.user.login_service)
6 changes: 0 additions & 6 deletions remoteappmanager/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,3 @@ class User(HasTraits):

#: Reference to the authenticator method used for user login
login_service = Unicode()

@property
def demo_applications(self):
"""Can be implemented to provide any default applications
granted by the user"""
return []