Added password change form
This commit is contained in:
parent
a9006bf1bc
commit
5536e764e7
8 changed files with 111 additions and 10 deletions
17
app/templates/change_password.html
Normal file
17
app/templates/change_password.html
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block body %}
|
||||
<h2>Change Password</h2>
|
||||
|
||||
<form method="POST">
|
||||
<dl>
|
||||
<dt>Old password:</dt>
|
||||
<dd><input type="password" name="old_password"></dd>
|
||||
<dt>New password:</dt>
|
||||
<dd><input type="password" name="new_password"></dd>
|
||||
<dt>New password, again:</dt>
|
||||
<dd><input type="password" name="confirm_password"></dd>
|
||||
<dd><input type="submit" value="Save"></dd>
|
||||
</dl>
|
||||
</form>
|
||||
{% endblock %}
|
||||
22
app/templates/confirm_delete.html
Normal file
22
app/templates/confirm_delete.html
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{% extends "base.html" %}
|
||||
|
||||
{% block body %}
|
||||
<h2>Confirm Deletion</h2>
|
||||
|
||||
<p>Are you sure you want to permanently delete this post?
|
||||
Neither you nor others will be able to see it;
|
||||
you cannot recover a post after it's deleted.</p>
|
||||
|
||||
<p>If you only want to hide it from the public,
|
||||
you can <a href="/edit/{{ message.id }}">set its privacy</a> to "Only me".</p>
|
||||
|
||||
<p>Here's the content of the message for reference:</p>
|
||||
|
||||
<ul>
|
||||
<li>{% include "includes/message.html" %}</li>
|
||||
</ul>
|
||||
|
||||
<form method="POST">
|
||||
<input type="submit" value="Delete">
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
<ul class="message-options">
|
||||
{% if message.user == current_user %}
|
||||
<li><a href="/edit/{{ message.id }}">Edit or change privacy</a></li>
|
||||
<!--li><a href="/confirm_delete/{{ message.id }}">Delete</a></li-->
|
||||
<li><a href="/delete/{{ message.id }}">Delete permanently</a></li>
|
||||
{% else %}
|
||||
<!--li><a href="/report/{{ message.id }}">Report</a></li-->
|
||||
{% endif %}
|
||||
|
|
|
|||
0
app/templates/user_list.html
Executable file → Normal file
0
app/templates/user_list.html
Executable file → Normal file
34
app/utils.py
34
app/utils.py
|
|
@ -2,10 +2,9 @@
|
|||
A list of utilities used across modules.
|
||||
'''
|
||||
|
||||
import datetime, re, base64, hashlib, string
|
||||
import datetime, re, base64, hashlib, string, sys, json
|
||||
from .models import User, Notification
|
||||
from flask import abort, render_template, request, session
|
||||
import sys, json
|
||||
|
||||
_forbidden_extensions = 'com net org txt'.split()
|
||||
_username_characters = frozenset(string.ascii_letters + string.digits + '_')
|
||||
|
|
@ -43,7 +42,7 @@ def int_to_b64(n):
|
|||
return base64.b64encode(b).lstrip(b'A').decode()
|
||||
|
||||
def pwdhash(s):
|
||||
return hashlib.md5((request.form['password']).encode('utf-8')).hexdigest()
|
||||
return hashlib.md5(s.encode('utf-8')).hexdigest()
|
||||
|
||||
def get_object_or_404(model, *expressions):
|
||||
try:
|
||||
|
|
@ -160,3 +159,32 @@ def tokenize(characters, table):
|
|||
break
|
||||
pos = mo.end(0)
|
||||
return tokens
|
||||
|
||||
def get_secret_key():
|
||||
from . import app
|
||||
secret_key = app.config['SECRET_KEY']
|
||||
if isinstance(secret_key, str):
|
||||
secret_key = secret_key.encode('utf-8')
|
||||
return secret_key
|
||||
|
||||
def generate_access_token(user):
|
||||
'''
|
||||
Generate access token for public API.
|
||||
'''
|
||||
h = hashlib.sha256(get_secret_key())
|
||||
h.update(b':')
|
||||
h.update(str(user.id).encode('utf-8'))
|
||||
h.update(b':')
|
||||
h.update(str(user.password).encode('utf-8'))
|
||||
return str(user.id) + ':' + h.hexdigest()[:32]
|
||||
|
||||
def check_access_token(user, token):
|
||||
uid, hh = token.split(':')
|
||||
if uid != user.get_id():
|
||||
return False
|
||||
h = hashlib.sha256(get_secret_key())
|
||||
h.update(b':')
|
||||
h.update(str(user.id).encode('utf-8'))
|
||||
h.update(b':')
|
||||
h.update(str(user.password).encode('utf-8'))
|
||||
return h.hexdigest()[:32] == hh
|
||||
|
|
|
|||
|
|
@ -29,8 +29,7 @@ def private_timeline():
|
|||
.where((Message.user << user.following())
|
||||
| (Message.user == user))
|
||||
.order_by(Message.pub_date.desc()))
|
||||
# TODO change to "feed.html"
|
||||
return object_list('private_messages.html', messages, 'message_list')
|
||||
return object_list('feed.html', messages, 'message_list')
|
||||
|
||||
@bp.route('/explore/')
|
||||
def public_timeline():
|
||||
|
|
@ -246,9 +245,15 @@ def edit(id):
|
|||
return redirect(url_for('website.user_detail', username=user.username))
|
||||
return render_template('edit.html', message=message)
|
||||
|
||||
#@bp.route('/delete/<int:id>', methods=['GET', 'POST'])
|
||||
#def confirm_delete(id):
|
||||
# return render_template('confirm_delete.html')
|
||||
@bp.route('/delete/<int:id>', methods=['GET', 'POST'])
|
||||
def confirm_delete(id):
|
||||
user = get_current_user()
|
||||
message = get_object_or_404(Message, Message.id == id)
|
||||
if message.user != user:
|
||||
abort(404)
|
||||
if request.method == 'POST':
|
||||
abort(501, 'CSRF-Token missing.')
|
||||
return render_template('confirm_delete.html', message=message)
|
||||
|
||||
# Workaround for problems related to invalid data.
|
||||
# Without that, changes will be lost across requests.
|
||||
|
|
@ -261,7 +266,8 @@ def profile_checkpoint():
|
|||
year=int(request.form['year'] if request.form.get('has_year') else '0'),
|
||||
website=request.form['website'] or None,
|
||||
instagram=request.form['instagram'] or None,
|
||||
facebook=request.form['facebook'] or None
|
||||
facebook=request.form['facebook'] or None,
|
||||
telegram=request.form['telegram'] or None
|
||||
)
|
||||
|
||||
@bp.route('/edit_profile/', methods=['GET', 'POST'])
|
||||
|
|
@ -299,6 +305,30 @@ def edit_profile():
|
|||
return redirect(url_for('website.user_detail', username=username))
|
||||
return render_template('edit_profile.html')
|
||||
|
||||
@bp.route('/change_password/', methods=['GET', 'POST'])
|
||||
def change_password():
|
||||
user = get_current_user()
|
||||
if request.method == 'POST':
|
||||
old_password = request.form['old_password']
|
||||
new_password = request.form['new_password']
|
||||
confirm_password = request.form['confirm_password']
|
||||
errors = False
|
||||
if not new_password:
|
||||
flash('Password cannot be empty')
|
||||
errors = True
|
||||
if new_password != confirm_password:
|
||||
flash('Password mismatch')
|
||||
errors = True
|
||||
if pwdhash(old_password) != user.password:
|
||||
flash('The old password is incorrect')
|
||||
errors = True
|
||||
if not errors:
|
||||
user.update(
|
||||
password=pwdhash(new_password)
|
||||
)
|
||||
return redirect(url_for('website.edit_profile'))
|
||||
return render_template('change_password.html')
|
||||
|
||||
@bp.route('/notifications/')
|
||||
@login_required
|
||||
def notifications():
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue