diff options
-rw-r--r-- | app/models.py | 2 | ||||
-rw-r--r-- | app/templates/users/set_password.html | 28 | ||||
-rw-r--r-- | app/templates/users/user_profile_page.html | 12 | ||||
-rw-r--r-- | app/views/users.py | 59 |
4 files changed, 97 insertions, 4 deletions
diff --git a/app/models.py b/app/models.py index fbd8bad..67a6677 100644 --- a/app/models.py +++ b/app/models.py @@ -97,7 +97,7 @@ class User(db.Model, UserMixin): # User authentication information username = db.Column(db.String(50), nullable=False, unique=True) - password = db.Column(db.String(255), nullable=False, server_default="") + password = db.Column(db.String(255), nullable=True) reset_password_token = db.Column(db.String(100), nullable=False, server_default="") rank = db.Column(db.Enum(UserRank)) diff --git a/app/templates/users/set_password.html b/app/templates/users/set_password.html new file mode 100644 index 0000000..6fc12ba --- /dev/null +++ b/app/templates/users/set_password.html @@ -0,0 +1,28 @@ +{% extends "base.html" %} + +{% block title %} + Set Password +{% endblock %} + +{% block content %} +<h1>Set Password</h1> + +{% from "macros/forms.html" import render_field, render_submit_field %} +<form action="" method="POST" class="form" role="form"> + <div class="row"> + <div class="col-sm-6 col-md-5 col-lg-4"> + {{ form.hidden_tag() }} + + {% if not current_user.email %} + {{ render_field(form.email, tabindex=230) }} + {% endif %} + + {{ render_field(form.password, tabindex=230) }} + {{ render_field(form.password2, tabindex=240) }} + + {{ render_submit_field(form.submit, tabindex=280) }} + </div> + </div> +</form> + +{% endblock %} diff --git a/app/templates/users/user_profile_page.html b/app/templates/users/user_profile_page.html index 062e9e8..c1cdb00 100644 --- a/app/templates/users/user_profile_page.html +++ b/app/templates/users/user_profile_page.html @@ -42,6 +42,18 @@ {% endif %} </td> </tr> + {% if user == current_user %} + <tr> + <td>Password:</td> + <td> + {% if user.password %} + Set | <a href="{{ url_for('user.change_password') }}">Change</a> + {% else %} + Not set | <a href="{{ url_for('set_password_page') }}">Set</a> + {% endif %} + </td> + </tr> + {% endif %} </table> </div> diff --git a/app/views/users.py b/app/views/users.py index b533856..478596b 100644 --- a/app/views/users.py +++ b/app/views/users.py @@ -101,8 +101,61 @@ def user_profile_page(username): return render_template("users/user_profile_page.html", user=user, form=form, packages=packages) +class SetPasswordForm(FlaskForm): + email = StringField("Email (Optional)", [Optional(), Email()]) + password = PasswordField("New password", [InputRequired(), Length(2, 20)]) + password2 = PasswordField("Verify password", [InputRequired(), Length(2, 20)]) + submit = SubmitField("Save") + +@app.route("/user/set-password/", methods=["GET", "POST"]) +@login_required +def set_password_page(): + if current_user.password is not None: + return redirect(url_for("user.change_password")) + + form = SetPasswordForm(request.form) + if request.method == "POST" and form.validate(): + one = form.password.data + two = form.password2.data + if one == two: + # Hash password + hashed_password = user_manager.hash_password(form.password.data) + + # Change password + user_manager.update_password(current_user, hashed_password) + + # Send 'password_changed' email + if user_manager.enable_email and user_manager.send_password_changed_email and current_user.email: + emails.send_password_changed_email(current_user) + + # Send password_changed signal + signals.user_changed_password.send(current_app._get_current_object(), user=current_user) + + # Prepare one-time system message + flash('Your password has been changed successfully.', 'success') + + newEmail = form["email"].data + if newEmail != current_user.email and newEmail.strip() != "": + token = randomString(32) + + ver = UserEmailVerification() + ver.user = current_user + ver.token = token + ver.email = newEmail + db.session.add(ver) + db.session.commit() + + task = sendVerifyEmail.delay(newEmail, token) + return redirect(url_for("check_task", id=task.id, r=url_for("user_profile_page", username=current_user.username))) + else: + return redirect(url_for("user_profile_page", username=current_user.username)) + else: + flash("Passwords do not match", "error") + + return render_template("users/set_password.html", form=form) + -@app.route("/users/claim/", methods=["GET", "POST"]) +@app.route("/user/claim/", methods=["GET", "POST"]) def user_claim_page(): username = request.args.get("username") if username is None: @@ -129,7 +182,7 @@ def user_claim_page(): cache.set("forum_claim_key_" + request.remote_addr, token, 5*60) if request.method == "POST": - ctype = request.form.get("claim_type") + ctype = request.form.get("claim_type") username = request.form.get("username") if username is None or len(username.strip()) < 2: @@ -161,7 +214,7 @@ def user_claim_page(): db.session.commit() if loginUser(user): - return redirect(url_for("user_profile_page", username=username)) + return redirect(url_for("set_password_page")) else: flash("Unable to login as user", "error") return redirect(url_for("user_claim_page", username=username)) |