From 0bf30641b1a2ec43b7b8ac4439df73429d007b23 Mon Sep 17 00:00:00 2001 From: YuviPanda Date: Tue, 18 May 2021 02:56:59 +0530 Subject: [PATCH] Support username / password auth provider Uses a 'database' connector[1] with auth0 to provide username / password authentication. demo.cloudbank.2i2c.cloud is now moved over to this, making it easier for people to give demos. This also removes any current restrictions on who can log in, and opens it up to everyone. We add some resource restrictions to match this. Fixes https://github.com/2i2c-org/pilot-hubs/issues/403 [1]: https://auth0.com/docs/connections/database --- config/hubs/cloudbank.cluster.yaml | 20 ++++++++++---------- config/hubs/schema.yaml | 3 ++- deployer/auth.py | 22 ++++++++++++++++++++-- deployer/hub.py | 3 ++- 4 files changed, 34 insertions(+), 14 deletions(-) diff --git a/config/hubs/cloudbank.cluster.yaml b/config/hubs/cloudbank.cluster.yaml index 8751273d8e..f527944e7d 100644 --- a/config/hubs/cloudbank.cluster.yaml +++ b/config/hubs/cloudbank.cluster.yaml @@ -186,7 +186,7 @@ hubs: domain: demo.cloudbank.2i2c.cloud template: basehub auth0: - connection: google-oauth2 + connection: password config: jupyterhub: homepage: @@ -206,15 +206,15 @@ hubs: url: http://cloudbank.org/ hub: config: - Authenticator: - allowed_users: &demo_users - - yuvipanda@gmail.com - - choldgraf@gmail.com - - georgiana.dolocan@gmail.com - - ericvd@gmail.com - - sean.smorris@berkeley.edu - - colliand@gmail.com - admin_users: *demo_users + JupyterHub: + # No more than 100 users at a time + active_server_limit: 100 + cull: + # Cull after 30min of inactivity + every: 300 + timeout: 1800 + # No pods over 12h long + maxAge: 43200 - name: lassen domain: lassen.cloudbank.2i2c.cloud template: basehub diff --git a/config/hubs/schema.yaml b/config/hubs/schema.yaml index ea2e2fd420..df718fa9a5 100644 --- a/config/hubs/schema.yaml +++ b/config/hubs/schema.yaml @@ -117,10 +117,11 @@ properties: properties: connection: type: string - enum: + enum: - google-oauth2 - github - ORCID + - password description: | Authentication method users of the hub can use to log in to the hub. We support a subset of the [connectors](https://auth0.com/docs/identityproviders) diff --git a/deployer/auth.py b/deployer/auth.py index ede9df2eee..ed473ecdef 100644 --- a/deployer/auth.py +++ b/deployer/auth.py @@ -6,7 +6,8 @@ USERNAME_KEYS = { 'github': 'nickname', 'google-oauth2': 'email', - 'ORCID': 'sub' + 'ORCID': 'sub', + 'password': 'email' } @@ -79,6 +80,7 @@ def _ensure_client_callback(self, client, domains): } ) + def ensure_client(self, name, domains, connection_name): current_clients = self.get_clients() if name not in current_clients: @@ -89,12 +91,28 @@ def ensure_client(self, name, domains, connection_name): self._ensure_client_callback(client, domains) current_connections = self.get_connections() + + if connection_name == 'password': + db_connection_name = f'database-{name}' + + if db_connection_name not in current_connections: + # connection doesn't exist yet, create it + connection = self.auth0.connections.create({ + 'name': db_connection_name, + 'display_name': name, + 'strategy': 'auth0' + }) + current_connections[db_connection_name] = connection + selected_connection_name = db_connection_name + else: + selected_connection_name = connection_name + for connection in current_connections.values(): # The chosen connection! enabled_clients = connection['enabled_clients'].copy() needs_update = False client_id = client['client_id'] - if connection['name'] == connection_name: + if connection['name'] == selected_connection_name: if client_id not in enabled_clients: enabled_clients.append(client_id) needs_update = True diff --git a/deployer/hub.py b/deployer/hub.py index a74742ca6e..451e618c93 100644 --- a/deployer/hub.py +++ b/deployer/hub.py @@ -1,3 +1,4 @@ +from auth import KeyProvider import hashlib import hmac import json @@ -100,7 +101,7 @@ def __init__(self, cluster, spec): self.cluster = cluster self.spec = spec - def get_generated_config(self, auth_provider, secret_key): + def get_generated_config(self, auth_provider: KeyProvider, secret_key): """ Generate config automatically for each hub