From 3440fe6f01154b38e7c215ad8e0f4f6f370af225 Mon Sep 17 00:00:00 2001
From: kaiyou <pierre@jaury.eu>
Date: Sat, 14 Sep 2019 20:21:30 +0200
Subject: [PATCH] Support signing up (without captcha for now)

---
 trurt/account/forms.py                        |  8 +++
 trurt/account/login.py                        | 40 +++++++++----
 trurt/account/templates/account_home.html     |  2 +-
 trurt/account/templates/account_register.html |  0
 ...account_login.html => account_signin.html} |  0
 trurt/account/templates/account_signup.html   |  8 +++
 trurt/manage.py                               | 16 ++---
 trurt/models.py                               | 18 +++++-
 trurt/templates/base.html                     | 58 ++++++++++---------
 trurt/templates/sidebar.html                  | 12 ++--
 trurt/utils.py                                |  2 +-
 11 files changed, 105 insertions(+), 59 deletions(-)
 delete mode 100644 trurt/account/templates/account_register.html
 rename trurt/account/templates/{account_login.html => account_signin.html} (100%)
 create mode 100644 trurt/account/templates/account_signup.html

diff --git a/trurt/account/forms.py b/trurt/account/forms.py
index b3b1c82c..f5a9f299 100644
--- a/trurt/account/forms.py
+++ b/trurt/account/forms.py
@@ -8,3 +8,11 @@ class LoginForm(flask_wtf.FlaskForm):
     username = fields.StringField(_('Username'), [validators.DataRequired()])
     password = fields.PasswordField(_('Password'), [validators.DataRequired()])
     submit = fields.SubmitField(_('Sign in'))
+
+
+class SignupForm(flask_wtf.FlaskForm):
+    username = fields.StringField(_('Username'), [validators.DataRequired()])
+    password = fields.PasswordField(_('Password'), [validators.DataRequired()])
+    password2 = fields.PasswordField(_('Confirm password'),
+        [validators.DataRequired(validators.EqualTo('password'))])
+    submit = fields.SubmitField(_('Sign in'))
diff --git a/trurt/account/login.py b/trurt/account/login.py
index 3f5cbfe4..4a631f45 100644
--- a/trurt/account/login.py
+++ b/trurt/account/login.py
@@ -5,8 +5,8 @@ import flask_login
 import flask
 
 
-@blueprint.route("/login", methods=["GET", "POST"])
-def login():
+@blueprint.route("/signin", methods=["GET", "POST"])
+def signin():
     form = forms.LoginForm()
     if form.validate_on_submit():
         user = models.User.login(form.username.data, form.password.data)
@@ -14,17 +14,35 @@ def login():
             flask_login.login_user(user)
             return flask.redirect(utils.url_or_intent(".home"))
         else:
-            flask.flash("Wrong credentials")
-    return flask.render_template("account_login.html",
-        action=utils.url_for(".login"), form=form)
+            flask.flash("Wrong credentials", "danger")
+    return flask.render_template("account_signin.html",
+        action=utils.url_for(".signin"), form=form)
 
 
-@blueprint.route("/logout")
-def logout():
+@blueprint.route("/signout")
+def signout():
     flask_login.logout_user()
-    return flask.redirect("/")
+    return flask.redirect(flask.url_for(".signin"))
 
 
-@blueprint.route("/register")
-def register():
-    return flask.redirect("/")
+@blueprint.route("/signup", methods=["GET", "POST"])
+def signup():
+    form = forms.SignupForm()
+    if form.validate_on_submit():
+        conflict = models.User.query.filter_by(username=form.username.data).first()
+        if conflict:
+            flask.flash("A user with the same username exists already", "danger")
+        else:
+            user = models.User()
+            user.username = form.username.data
+            auth = models.Auth()
+            auth.set_password(form.password.data)
+            user.auths.append(auth)
+            models.db.session.add(user)
+            models.db.session.add(auth)
+            models.log(models.History.SIGNUP,
+                comment="Signed up using the Web form", user=user)
+            models.db.session.commit()
+            flask.flash("User created successfully", "success")
+            return flask.redirect(utils.url_or_intent("account.home"))
+    return flask.render_template("account_signup.html", form=form)
diff --git a/trurt/account/templates/account_home.html b/trurt/account/templates/account_home.html
index e1a375d0..02dbb6e2 100644
--- a/trurt/account/templates/account_home.html
+++ b/trurt/account/templates/account_home.html
@@ -1,7 +1,7 @@
 {% extends "base.html" %}
 
 {% block title %}My account{% endblock %}
-{% block subtitle %}overview of {{ current_user.username }}{% endblock %}
+{% block subtitle %}status and history{% endblock %}
 
 {% block content %}
 <div class="row">
diff --git a/trurt/account/templates/account_register.html b/trurt/account/templates/account_register.html
deleted file mode 100644
index e69de29b..00000000
diff --git a/trurt/account/templates/account_login.html b/trurt/account/templates/account_signin.html
similarity index 100%
rename from trurt/account/templates/account_login.html
rename to trurt/account/templates/account_signin.html
diff --git a/trurt/account/templates/account_signup.html b/trurt/account/templates/account_signup.html
new file mode 100644
index 00000000..25684874
--- /dev/null
+++ b/trurt/account/templates/account_signup.html
@@ -0,0 +1,8 @@
+{% extends "base.html" %}
+
+{% block title %}Sign up{% endblock %}
+{% block subtitle %}create a new account{% endblock %}
+
+{% block content %}
+{{ macros.form(form) }}
+{% endblock %}
diff --git a/trurt/manage.py b/trurt/manage.py
index f88e06c6..64f0fba6 100644
--- a/trurt/manage.py
+++ b/trurt/manage.py
@@ -23,10 +23,8 @@ def create_user(username, password):
     auth = models.Auth()
     auth.set_password(password)
     user.auths.append(auth)
-    event = models.History()
-    event.user = user
-    event.category = models.History.REGISTER
-    event.comment = "Created from the command line"
+    models.log(models.History.SIGNUP,
+        comment="Created from the command line", user=user)
     models.db.session.add(event)
     models.db.session.add(user)
     models.db.session.add(auth)
@@ -45,13 +43,9 @@ def create_profile(username, service_uuid, profile_username):
     profile.user = user
     profile.service = service
     profile.username = profile_username
-    event = models.History()
-    event.user = user
-    event.service = service
-    event.profile = profile
-    event.category = models.History.CREATE
-    event.value = profile.username
-    event.comment = "Created from the command line"
+    models.log(models.History.CREATE,
+        comment="Create from the command line", user=user,
+        service=service, profile=profile)
     models.db.session.add(event)
     models.db.session.add(profile)
     models.db.session.commit()
diff --git a/trurt/models.py b/trurt/models.py
index 4dc8553f..3fafe9f0 100644
--- a/trurt/models.py
+++ b/trurt/models.py
@@ -9,6 +9,20 @@ import json
 import uuid
 
 
+def log(category, value=None, comment=None, user=None, profile=None, service=None, actor=None):
+    """ Log a history event
+    """
+    event = History()
+    event.category = category
+    event.value = value
+    event.comment = comment
+    event.user = user
+    event.profile = profile
+    event.service = service
+    event.actor = actor
+    db.session.add(event)
+
+
 class Base(flask_sqlalchemy.Model):
     """ Base class for all models
     """
@@ -154,14 +168,14 @@ class History(db.Model):
     """
     __tablename__ = "history"
 
-    REGISTER = "register"
+    SIGNUP = "signup"
     CREATE = "create"
     DELETE = "delete"
     NOTE = "note"
     STATUS = "status"
 
     DESCRIPTION = {
-        REGISTER: "registered this account",
+        SIGNUP: "signed up for this account",
         CREATE: "created the profile {this.profile.username} on {this.service.name}",
     }
 
diff --git a/trurt/templates/base.html b/trurt/templates/base.html
index 3b7b8f30..a5718e38 100644
--- a/trurt/templates/base.html
+++ b/trurt/templates/base.html
@@ -16,33 +16,34 @@
         </a>
 
         <nav class="navbar navbar-static-top">
-        <a href="#" class="sidebar-toggle" data-toggle="push-menu" role="button">
-          <span class="sr-only">Toggle navigation</span>
-        </a>
-        <div class="navbar-custom-menu">
-          <ul class="nav navbar-nav">
-            {% if current_user.is_authenticated %}
-            <li class="dropdown user">
-              <a class="dropdown-toggle">
-                Logged in as <strong>{{ current_user.username }}</strong>
-              </a>
-            </li>
-            <li class="dropdown user">
-              <a href="{{ url_for("account.logout") }}" class="dropdown-toggle">
-                <i class="fa fa-sign-out"></i>
-                Log out
-              </a>
-            </li>
-            {% else %}
-            <li class="dropdown user">
-              <a href="{{ url_for("account.login") }}" class="dropdown-toggle">
-                <i class="fa fa-sign-in"></i>
-                Log in
-              </a>
-            </li>
-            {% endif %}
-          </ul>
-        </div>
+          <a href="#" class="sidebar-toggle" data-toggle="push-menu" role="button">
+            <span class="sr-only">Toggle navigation</span>
+          </a>
+          <div class="navbar-custom-menu">
+            <ul class="nav navbar-nav">
+              {% if current_user.is_authenticated %}
+              <li class="dropdown user">
+                <a class="dropdown-toggle">
+                  Logged in as <strong>{{ current_user.username }}</strong>
+                </a>
+              </li>
+              <li class="dropdown user">
+                <a href="{{ url_for("account.signout") }}" class="dropdown-toggle">
+                  <i class="fa fa-sign-out"></i>
+                  Sign out
+                </a>
+              </li>
+              {% else %}
+              <li class="dropdown user">
+                <a href="{{ url_for("account.signin") }}" class="dropdown-toggle">
+                  <i class="fa fa-sign-in"></i>
+                  Sign in
+                </a>
+              </li>
+              {% endif %}
+            </ul>
+          </div>
+        </nav>
 
       </header>
 
@@ -62,6 +63,9 @@
           </h1>
         </section>
         <section class="content container-fluid">
+          {% for category, message in get_flashed_messages(with_categories=True) or [] %}
+          <div class="alert alert-{{ category or "info" }}">{{ message }}</div>
+          {% endfor %}
           {% block content %}{% endblock %}
         </section>
       </div>
diff --git a/trurt/templates/sidebar.html b/trurt/templates/sidebar.html
index 3dc17b70..87885635 100644
--- a/trurt/templates/sidebar.html
+++ b/trurt/templates/sidebar.html
@@ -11,19 +11,19 @@
   </a>
 </li>
 <li>
-  <a href="{{ url_for("account.logout") }}">
-    <i class="fa fa-sign-out"></i> <span>Log out</span>
+  <a href="{{ url_for("account.signout") }}">
+    <i class="fa fa-sign-out"></i> <span>Sign out</span>
   </a>
 </li>
 {% else %}
 <li>
-  <a href="{{ url_for("account.register") }}">
-    <i class="fa fa-user-plus"></i> <span>Register</span>
+  <a href="{{ url_for("account.signup") }}">
+    <i class="fa fa-user-plus"></i> <span>Sign up</span>
   </a>
 </li>
 <li>
-  <a href="{{ url_for("account.login") }}">
-    <i class="fa fa-sign-in"></i> <span>Log in</span>
+  <a href="{{ url_for("account.signin") }}">
+    <i class="fa fa-sign-in"></i> <span>Sign in</span>
   </a>
 </li>
 {% endif %}
diff --git a/trurt/utils.py b/trurt/utils.py
index bc53f4a1..53a05a5f 100644
--- a/trurt/utils.py
+++ b/trurt/utils.py
@@ -15,7 +15,7 @@ INTENTS = "intents"
 @login.unauthorized_handler
 def handle_needs_login():
     return flask.redirect(
-        url_for('account.login', intent=flask.request.endpoint)
+        url_for('account.signin', intent=flask.request.endpoint)
     )
 
 
-- 
GitLab