diff --git a/docs/options.rst b/docs/options.rst index bd4009e..be8a260 100644 --- a/docs/options.rst +++ b/docs/options.rst @@ -48,3 +48,14 @@ open signup, where all users that do sign up can already log in the system. To d .. code-block:: python c.Authenticator.open_signup = True + + +Ask for extra information on SignUp +----------------------------------- + +Native Authenticator is based on username and password only. But if you need extra information about the users, you can add them on the sign up. For now, you can ask for email by adding the following line: + + +.. code-block:: python + + c.Authenticator.ask_email_on_signup = True diff --git a/nativeauthenticator/handlers.py b/nativeauthenticator/handlers.py index 49325e8..4ce6159 100644 --- a/nativeauthenticator/handlers.py +++ b/nativeauthenticator/handlers.py @@ -30,7 +30,10 @@ class SignUpHandler(LocalBase): """Render the sign in page.""" async def get(self): self._register_template_path() - html = self.render_template('signup.html') + html = self.render_template( + 'signup.html', + ask_email=self.authenticator.ask_email_on_signup, + ) self.finish(html) def get_result_message(self, user): @@ -57,6 +60,7 @@ async def post(self): html = self.render_template( 'signup.html', + ask_email=self.authenticator.ask_email_on_signup, result_message=message, alert=alert ) @@ -68,8 +72,11 @@ class AuthorizationHandler(LocalBase): @admin_only async def get(self): self._register_template_path() - html = self.render_template('autorization-area.html', - users=self.db.query(UserInfo).all()) + html = self.render_template( + 'autorization-area.html', + ask_email=self.authenticator.ask_email_on_signup, + users=self.db.query(UserInfo).all(), + ) self.finish(html) diff --git a/nativeauthenticator/nativeauthenticator.py b/nativeauthenticator/nativeauthenticator.py index 6c8b934..dfaea85 100644 --- a/nativeauthenticator/nativeauthenticator.py +++ b/nativeauthenticator/nativeauthenticator.py @@ -45,6 +45,11 @@ class NativeAuthenticator(Authenticator): help=("Allows every user that made sign up to automatically log in " "the system without needing admin authorization") ) + ask_email_on_signup = Bool( + config=True, + default=False, + help="Asks for email on signup" + ) def __init__(self, add_new_table=True, *args, **kwargs): super().__init__(*args, **kwargs) @@ -128,7 +133,7 @@ def is_password_strong(self, password): return all(checks) - def get_or_create_user(self, username, pw): + def get_or_create_user(self, username, pw, **kwargs): user = UserInfo.find(self.db, username) if user: return user @@ -138,6 +143,7 @@ def get_or_create_user(self, username, pw): encoded_pw = bcrypt.hashpw(pw.encode(), bcrypt.gensalt()) infos = {'username': username, 'password': encoded_pw} + infos.update(kwargs) if username in self.admin_users or self.open_signup: infos.update({'is_authorized': True}) diff --git a/nativeauthenticator/orm.py b/nativeauthenticator/orm.py index d173b17..740e235 100644 --- a/nativeauthenticator/orm.py +++ b/nativeauthenticator/orm.py @@ -1,9 +1,9 @@ import bcrypt +import re from jupyterhub.orm import Base -from sqlalchemy import ( - Boolean, Column, Integer, String -) +from sqlalchemy import Boolean, Column, Integer, String +from sqlalchemy.orm import validates class UserInfo(Base): @@ -12,6 +12,7 @@ class UserInfo(Base): username = Column(String, nullable=False) password = Column(String, nullable=False) is_authorized = Column(Boolean, default=False) + email = Column(String) @classmethod def find(cls, db, username): @@ -31,3 +32,9 @@ def change_authorization(cls, db, username): user.is_authorized = not user.is_authorized db.commit() return user + + @validates('email') + def validate_email(self, key, address): + assert re.match(r"^[A-Za-z0-9\.\+_-]+@[A-Za-z0-9\._-]+\.[a-zA-Z]*$", + address) + return address diff --git a/nativeauthenticator/templates/autorization-area.html b/nativeauthenticator/templates/autorization-area.html index 992f68c..cd09e64 100644 --- a/nativeauthenticator/templates/autorization-area.html +++ b/nativeauthenticator/templates/autorization-area.html @@ -10,6 +10,9 @@

Authorization Area

Username + {% if ask_email %} + Email + {% endif %} Is Authorized? @@ -18,6 +21,9 @@

Authorization Area

{% if user.is_authorized %} {{ user.username }} + {% if ask_email %} + {{ user.email }} + {% endif %} Yes Authorization Area {% else %} {{ user.username }} + {% if ask_email %} + {{ user.email }} + {% endif %} No name="username" id="username_input" tabindex="2" + required /> + {% if ask_email %} + + + {% endif %}
name="password" id="pwd" tabindex="2" + required />