Browse Source

halfway implementation of forgotten passwords

current_wdka_release
crunk 3 years ago
parent
commit
730a12accd
  1. 9
      requirements.txt
  2. 7
      verse/app.py
  3. 19
      verse/forms/forgotpasswordform.py
  4. 14
      verse/start.py
  5. 34
      verse/statuspengguna/forgotpassword.py
  6. 29
      verse/templates/forgotpassword.html
  7. 2
      verse/usermodel.py

9
requirements.txt

@ -2,9 +2,11 @@ alembic==1.7.5
Babel==2.9.1 Babel==2.9.1
bcrypt==3.2.0 bcrypt==3.2.0
black==21.11b1 black==21.11b1
bleach==4.1.0
blinker==1.4 blinker==1.4
cffi==1.15.0 cffi==1.15.0
click==8.0.3 click==8.0.3
distribusi @ git+file:///home/shambler/Development/distribusiverse/distribusi@e291e7497e40211c2ebd54ca32a1f4bdaed71230
dnspython==2.1.0 dnspython==2.1.0
email-validator==1.1.3 email-validator==1.1.3
Flask==2.0.2 Flask==2.0.2
@ -15,6 +17,7 @@ Flask-Mail==0.9.1
Flask-Migrate==3.1.0 Flask-Migrate==3.1.0
Flask-Principal==0.4.0 Flask-Principal==0.4.0
Flask-Security==3.0.0 Flask-Security==3.0.0
Flask-Security-Too==4.1.3
Flask-SQLAlchemy==2.5.1 Flask-SQLAlchemy==2.5.1
Flask-WTF==1.0.0 Flask-WTF==1.0.0
greenlet==1.1.2 greenlet==1.1.2
@ -24,11 +27,13 @@ Jinja2==3.0.3
Mako==1.1.6 Mako==1.1.6
MarkupSafe==2.0.1 MarkupSafe==2.0.1
mypy-extensions==0.4.3 mypy-extensions==0.4.3
packaging==21.3
passlib==1.7.4 passlib==1.7.4
pathspec==0.9.0 pathspec==0.9.0
Pillow==8.3.2 Pillow==8.3.2
platformdirs==2.4.0 platformdirs==2.4.0
pycparser==2.21 pycparser==2.21
pyparsing==3.0.7
python-magic==0.4.24 python-magic==0.4.24
pytz==2021.3 pytz==2021.3
regex==2021.11.10 regex==2021.11.10
@ -36,7 +41,7 @@ six==1.16.0
speaklater==1.3 speaklater==1.3
SQLAlchemy==1.4.27 SQLAlchemy==1.4.27
tomli==1.2.2 tomli==1.2.2
typing-extensions==4.0.1 typing_extensions==4.0.1
webencodings==0.5.1
Werkzeug==2.0.2 Werkzeug==2.0.2
WTForms==3.0.0 WTForms==3.0.0
-e git+https://git.vvvvvvaria.org/crunk/distribusi-verse.git@1a50898d216ae95c3eb9c144bb7ec678e638daa6#egg=distribusi

7
verse/app.py

@ -22,6 +22,13 @@ def create_app():
APP.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True APP.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True
APP.config["MAX_CONTENT_LENGTH"] = 150 * 1024 * 1024 APP.config["MAX_CONTENT_LENGTH"] = 150 * 1024 * 1024
APP.config["MAIL_SERVER"] = "0.0.0.0"
APP.config["MAIL_PORT"] = 1025
APP.config["MAIL_USE_SSL"] = False
APP.config["MAIL_USE_TLS"] = True
# APP.config['MAIL_USERNAME'] = 'username'
# APP.config['MAIL_PASSWORD'] = 'password'
login_manager.session_protection = "strong" login_manager.session_protection = "strong"
login_manager.login_view = "index" login_manager.login_view = "index"
login_manager.login_message_category = "info" login_manager.login_message_category = "info"

19
verse/forms/forgotpasswordform.py

@ -0,0 +1,19 @@
"""Forgotten password form to help user."""
from wtforms import (
StringField,
SubmitField,
)
from wtforms import validators
from wtforms.validators import Length, Email
from flask_wtf import FlaskForm
class ForgotPasswordForm(FlaskForm):
"""Forgotten password distribusiverse form class."""
email = StringField(
"Email address:",
validators=[validators.InputRequired(), Email(), Length(6, 64)],
)
submit = SubmitField("Send email")

14
verse/start.py

@ -12,6 +12,7 @@ from flask_login import (
login_required, login_required,
current_user, current_user,
) )
from flask_mail import Mail
from flask_wtf.csrf import CSRFError from flask_wtf.csrf import CSRFError
from app import create_app, login_manager from app import create_app, login_manager
from usermodel import User from usermodel import User
@ -31,11 +32,13 @@ from uploadpage import UploadPage
from statuspengguna.helper import ResetUserState from statuspengguna.helper import ResetUserState
from statuspengguna.loginuser import LoginUser from statuspengguna.loginuser import LoginUser
from statuspengguna.registeruser import RegisterUser from statuspengguna.registeruser import RegisterUser
from statuspengguna.forgotpassword import ForgotPassword
from distribusisinfo import DistribusisInfo from distribusisinfo import DistribusisInfo
APP = create_app() APP = create_app()
stash_page = Blueprint("stash_page", __name__, static_folder="stash") stash_page = Blueprint("stash_page", __name__, static_folder="stash")
APP.register_blueprint(stash_page) APP.register_blueprint(stash_page)
mail = Mail(APP)
@APP.before_request @APP.before_request
@ -129,14 +132,17 @@ def logout():
@APP.route("/login", methods=["GET", "POST"]) @APP.route("/login", methods=["GET", "POST"])
def login(): def login():
result = LoginUser() return LoginUser()
return result
@APP.route("/register", methods=["GET", "POST"]) @APP.route("/register", methods=["GET", "POST"])
def register(): def register():
result = RegisterUser() return RegisterUser()
return result
@APP.route("/forgotpassword", methods=["GET", "POST"])
def forgotpassword():
return ForgotPassword(mail)
@APP.errorhandler(CSRFError) @APP.errorhandler(CSRFError)

34
verse/statuspengguna/forgotpassword.py

@ -0,0 +1,34 @@
from flask import render_template
from usermodel import User
from forms.forgotpasswordform import ForgotPasswordForm
from flask_mail import Message
def ForgotPassword(mail):
forgotpasswordform = ForgotPasswordForm()
if forgotpasswordform.validate_on_submit():
user = User.query.filter_by(
email=forgotpasswordform.email.data
).first()
if user is not None:
ResetPassWordMessage(user, mail)
forgotpasswordform.email.errors.append(
f"""If {forgotpasswordform.email.data} exists, an email is send with
a password reset link. (If your inbox doesn't
contain any new mail, please check your spam folder.)"""
)
return render_template(
"forgotpassword.html", forgotpasswordform=forgotpasswordform
)
def ResetPassWordMessage(user, mail):
msg = Message(
"Distribusiverse Forgotten Password ",
sender=("Distribusiverse mailer", "test@this.com"),
recipients=[user.email],
)
msg.html = f"""You have requested a password reset for Distribusiverse.<br>
<a href='http://localhost:5000/resetpassword/{user.email}'>Click here to
reset your password and make a new one.</a>"""
mail.send(msg)

29
verse/templates/forgotpassword.html

@ -0,0 +1,29 @@
{% extends "base.html" %}
{% block main %}
<div id="mainworkflow">
<div class="workflow">
<h2>Forgot your password?</h2>
<p>
Enter the email address that was used to register with Distribusiverse.
</p>
<form class="form" action="{{ url_for('forgotpassword') }}" method="post">
{{ forgotpasswordform.csrf_token }}
<fieldset class="required">
{{ forgotpasswordform.email.label }}
{{ forgotpasswordform.email }}
{% for message in forgotpasswordform.email.errors %}
<div class="error">{{ message }}</div>
{% endfor %}
</fieldset>
<fieldset class="button required error">
{{ forgotpasswordform.submit }}
<div class="overview">
<a href="/">
<input type="button" name="button" value="Back to main page"></input>
</a>
</div>
</fieldset>
</form>
</div>
</div
{% endblock main %}

2
verse/usermodel.py

@ -12,6 +12,8 @@ class User(UserMixin, db.Model):
email = db.Column(db.String(150), unique=True, nullable=False) email = db.Column(db.String(150), unique=True, nullable=False)
password = db.Column(db.String(300), nullable=False, unique=False) password = db.Column(db.String(300), nullable=False, unique=False)
currentdistribusi = db.Column(db.String(300), nullable=True, unique=False) currentdistribusi = db.Column(db.String(300), nullable=True, unique=False)
# resethash = db.Column(db.String(300), nullable=True, unique=True)
# resettime = db.Column(db.DateTime)
tutor = db.Column(db.Boolean, default=False) tutor = db.Column(db.Boolean, default=False)
admin = db.Column(db.Boolean, default=False) admin = db.Column(db.Boolean, default=False)

Loading…
Cancel
Save