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

feat: use email as username #209

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions dev-jupyterhub_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
11 changes: 11 additions & 0 deletions docs/source/options.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 7 additions & 1 deletion nativeauthenticator/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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"]
)
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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"],
Expand Down
10 changes: 10 additions & 0 deletions nativeauthenticator/nativeauthenticator.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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:
Expand All @@ -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():
Expand Down
5 changes: 5 additions & 0 deletions nativeauthenticator/templates/native-login.html
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,12 @@
</p>
{% endif %}

{% if use_email_as_username %}
<label for="username_input">Email:</label>
{% else %}
<label for="username_input">Username:</label>
{% endif %}

<input id="username_input" type="text" name="username" val="{{username}}" autocapitalize="off" autocorrect="off" class="form-control" autofocus="autofocus" required />
<p></p>

Expand Down
2 changes: 2 additions & 0 deletions nativeauthenticator/templates/signup.html
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,11 @@
</div>
{% endif %}

{% if not use_email_as_username %}
<label for="username_input">Username:</label>
<input id="username_input" type="text" name="username" val="{{username}}" autocapitalize="off" autocorrect="off" class="form-control" autofocus="autofocus" required />
<p></p>
{% endif %}

{% if ask_email %}
<label for="email_input">Email:</label>
Expand Down