From 51e42f8e6f09a0999ae170348e9cb107c0dd8196 Mon Sep 17 00:00:00 2001
From: Romulo Rosa
Date: Tue, 14 Jun 2022 16:36:53 +0200
Subject: [PATCH] feat: use email as username
---
dev-jupyterhub_config.py | 2 ++
docs/source/options.md | 11 +++++++++++
nativeauthenticator/handlers.py | 8 +++++++-
nativeauthenticator/nativeauthenticator.py | 10 ++++++++++
nativeauthenticator/templates/native-login.html | 5 +++++
nativeauthenticator/templates/signup.html | 2 ++
6 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/dev-jupyterhub_config.py b/dev-jupyterhub_config.py
index 593974e..ba55670 100644
--- a/dev-jupyterhub_config.py
+++ b/dev-jupyterhub_config.py
@@ -26,6 +26,8 @@
c.NativeAuthenticator.enable_signup = True
c.NativeAuthenticator.open_signup = False
c.NativeAuthenticator.ask_email_on_signup = True
+c.NativeAuthenticator.use_email_as_username = True
+c.NativeAuthenticator.open_signup = True
c.NativeAuthenticator.allow_2fa = True
diff --git a/docs/source/options.md b/docs/source/options.md
index 1d3402d..f07383e 100644
--- a/docs/source/options.md
+++ b/docs/source/options.md
@@ -65,6 +65,17 @@ For now, the only extra information you can ask is email. To do so, you can add
c.NativeAuthenticator.ask_email_on_signup = True
```
+### Use email as username
+
+This option basically uses the email as username which prevents users from having to provide an username on the signup form
+
+```python
+c.NativeAuthenticator.use_email_as_username = True
+```
+
+If you are using DockerSpawner please notice that this have a direct impact on the container names since it uses the username to name the container.
+Also, if you are using dockerspawner < 12.0.0 you may face some issues due to a miss alginment with some changes done by the Docker team
+
## Use reCaptcha to prevent scripted SignUp attacks
Since by default, anybody can sign up to the system, you may want to use the lightweight
diff --git a/nativeauthenticator/handlers.py b/nativeauthenticator/handlers.py
index 757ccee..1584f08 100644
--- a/nativeauthenticator/handlers.py
+++ b/nativeauthenticator/handlers.py
@@ -59,6 +59,7 @@ async def get(self):
html = await self.render_template(
"signup.html",
ask_email=self.authenticator.ask_email_on_signup,
+ use_email_as_username=self.authenticator.use_email_as_username,
two_factor_auth=self.authenticator.allow_2fa,
recaptcha_key=self.authenticator.recaptcha_key,
tos=self.authenticator.tos,
@@ -169,11 +170,14 @@ async def post(self):
if assume_user_is_human:
user_info = {
- "username": self.get_body_argument("username", strip=False),
+ "username": self.get_body_argument("username", "", strip=False),
"password": self.get_body_argument("signup_password", strip=False),
"email": self.get_body_argument("email", "", strip=False),
"has_2fa": bool(self.get_body_argument("2fa", "", strip=False)),
}
+ if self.authenticator.use_email_as_username:
+ user_info["username"] = user_info["email"]
+
username_already_taken = self.authenticator.user_exists(
user_info["username"]
)
@@ -207,6 +211,7 @@ async def post(self):
html = await self.render_template(
"signup.html",
ask_email=self.authenticator.ask_email_on_signup,
+ use_email_as_username=self.authenticator.use_email_as_username,
result_message=message,
alert=alert,
two_factor_auth=self.authenticator.allow_2fa,
@@ -466,6 +471,7 @@ def _render(self, login_error=None, username=None):
"native-login.html",
next=url_escape(self.get_argument("next", default="")),
username=username,
+ use_email_as_username=self.authenticator.use_email_as_username,
login_error=login_error,
custom_html=self.authenticator.custom_html,
login_url=self.settings["login_url"],
diff --git a/nativeauthenticator/nativeauthenticator.py b/nativeauthenticator/nativeauthenticator.py
index 5af864a..a4d441a 100644
--- a/nativeauthenticator/nativeauthenticator.py
+++ b/nativeauthenticator/nativeauthenticator.py
@@ -149,6 +149,11 @@ class NativeAuthenticator(Authenticator):
)
ask_email_on_signup = Bool(False, config=True, help="Asks for email on signup")
+ use_email_as_username = Bool(
+ False,
+ config=True,
+ help="Use email as username. Note that this requires ask_email_on_signup to be True",
+ )
import_from_firstuse = Bool(
False, config=True, help="Import users from FirstUse Authenticator database"
@@ -181,6 +186,7 @@ def __init__(self, add_new_table=True, *args, **kwargs):
self.add_data_from_firstuse()
self.setup_self_approval()
+ self.setup_use_email_as_username()
def setup_self_approval(self):
if self.allow_self_approval_for:
@@ -193,6 +199,10 @@ def setup_self_approval(self):
"len > 8 when using self_approval"
)
+ def setup_use_email_as_username(self):
+ if self.use_email_as_username:
+ self.ask_email_on_signup = True
+
def add_new_table(self):
inspector = inspect(self.db.bind)
if "users_info" not in inspector.get_table_names():
diff --git a/nativeauthenticator/templates/native-login.html b/nativeauthenticator/templates/native-login.html
index 1435b67..0e4bf73 100644
--- a/nativeauthenticator/templates/native-login.html
+++ b/nativeauthenticator/templates/native-login.html
@@ -49,7 +49,12 @@
{% endif %}
+ {% if use_email_as_username %}
+
+ {% else %}
+ {% endif %}
+
diff --git a/nativeauthenticator/templates/signup.html b/nativeauthenticator/templates/signup.html
index 2db3b7a..0ca9946 100644
--- a/nativeauthenticator/templates/signup.html
+++ b/nativeauthenticator/templates/signup.html
@@ -72,9 +72,11 @@
{% endif %}
+ {% if not use_email_as_username %}
+ {% endif %}
{% if ask_email %}