Initial work on local passwords.
- Create password change modal on user dashboard - Split login into two flows -- WPI and local Need to define password strength requirements and create local login page, as well as allow for setting an alternative contact email.
This commit is contained in:
parent
83b3eef3bd
commit
87adc200b3
6 changed files with 101 additions and 5 deletions
|
@ -10,9 +10,12 @@ bp = Blueprint('auth', __name__, url_prefix='/auth')
|
|||
|
||||
from acmsite import oauth
|
||||
|
||||
|
||||
@bp.route('/login')
|
||||
@bp.route("/login")
|
||||
def login():
|
||||
return render_template('login.html')
|
||||
|
||||
@bp.route('/oauth')
|
||||
def oauth_redirect():
|
||||
return oauth.azure.authorize_redirect(url_for('auth.oauth2_callback',
|
||||
_external=True))
|
||||
|
||||
|
|
|
@ -1,9 +1,39 @@
|
|||
from werkzeug.security import generate_password_hash, check_password_hash
|
||||
from flask import Blueprint, render_template, request, flash, redirect, url_for
|
||||
from flask_login import current_user, login_required
|
||||
|
||||
from flask import Blueprint, render_template
|
||||
from acmsite.dashboard.forms import PasswordForm
|
||||
from acmsite import db
|
||||
|
||||
|
||||
bp = Blueprint('dashboard', __name__, url_prefix='/dashboard')
|
||||
|
||||
@bp.route("/")
|
||||
@login_required
|
||||
def home():
|
||||
return render_template('dashboard.html')
|
||||
form = PasswordForm()
|
||||
return render_template('dashboard.html', form=form)
|
||||
|
||||
@bp.route("/change_password", methods=["POST"])
|
||||
@login_required
|
||||
def change_password():
|
||||
form = PasswordForm(request.form)
|
||||
|
||||
if form.validate_on_submit():
|
||||
current_password = request.form.get("current_password")
|
||||
new_password = request.form.get("new_password")
|
||||
password_confirm = request.form.get("password_confirm")
|
||||
|
||||
if new_password == password_confirm:
|
||||
if current_password == '' and current_user.password == '':
|
||||
current_user.password = generate_password_hash(new_password)
|
||||
flash("Password set successfully.")
|
||||
elif check_password_hash(current_user.password, current_password):
|
||||
current_user.password = generate_password_hash(new_password)
|
||||
flash("Password updated successfully.")
|
||||
else:
|
||||
flash("Incorrect password.")
|
||||
else:
|
||||
flash("Passwords do not match!")
|
||||
db.session.commit()
|
||||
return redirect(url_for("dashboard.home"))
|
||||
|
|
9
acmsite/dashboard/forms.py
Normal file
9
acmsite/dashboard/forms.py
Normal file
|
@ -0,0 +1,9 @@
|
|||
from flask_wtf import FlaskForm
|
||||
from wtforms.fields import PasswordField
|
||||
from wtforms.validators import DataRequired
|
||||
|
||||
class PasswordForm(FlaskForm):
|
||||
current_password = PasswordField('Current Password')
|
||||
new_password = PasswordField('New Password', validators=[DataRequired()])
|
||||
password_confirm = PasswordField('Confirm New Password',
|
||||
validators=[DataRequired()])
|
|
@ -13,4 +13,46 @@
|
|||
unless you're an
|
||||
officer!</p>
|
||||
|
||||
<button type="button" class="btn btn-secondary" data-bs-toggle="modal"
|
||||
data-bs-target="#passwordModal">Change or Set
|
||||
Local Password</button>
|
||||
<!-- Modals -->
|
||||
<div class="modal" id="passwordModal" tabindex="-1" aria-labelledby="passwordModalLabel"
|
||||
aria-hidden="true">
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h1 class="modal-title fs-5" id="passwordModalLabel">Change Password</h1>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</div>
|
||||
<form class="form" id="edit-form" action="/dashboard/change_password" role="form" method="post">
|
||||
<div class="modal-body">
|
||||
{{ form.csrf_token }}
|
||||
<div class="form-floating mb-3 required">
|
||||
{{ form.current_password(class="form-control") }}
|
||||
{{ form.current_password.label() }}
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="form-floating mb-3 required">
|
||||
{{ form.new_password(class="form-control") }}
|
||||
{{ form.new_password.label() }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="form-floating mb-3 required">
|
||||
{{ form.password_confirm(class="form-control") }}
|
||||
{{ form.password_confirm.label() }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||
<button type="submit" class="btn btn-primary" id="edit-save">Save changes</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock app_content %}
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
{% endif %}
|
||||
{{ render_nav_item('auth.logout', 'Logout') }}
|
||||
{% else %}
|
||||
{{ render_nav_item('auth.login', 'Login with WPI') }}
|
||||
{{ render_nav_item('auth.login', 'Login') }}
|
||||
{% endif %}
|
||||
</ul>
|
||||
</div>
|
||||
|
|
12
acmsite/templates/login.html
Normal file
12
acmsite/templates/login.html
Normal file
|
@ -0,0 +1,12 @@
|
|||
{% extends "layout.html" %}
|
||||
|
||||
{% block app_content %}
|
||||
<h1>Login Methods</h1>
|
||||
|
||||
<div>
|
||||
<a class="btn btn-primary" href="{{ url_for('auth.oauth_redirect') }}">Login with WPI</a>
|
||||
</div>
|
||||
<div class="mt-1 mb-3">
|
||||
<a class="btn btn-secondary" href="">Login with Local Account</a>
|
||||
</div>
|
||||
{% endblock app_content %}
|
Loading…
Add table
Reference in a new issue