mirror of
https://codeberg.org/catask-org/catask.git
synced 2025-04-20 05:43:41 -05:00
improve blacklist, secure routes, add more routes...
This commit is contained in:
parent
82c6a8b67b
commit
0a98041a23
1 changed files with 35 additions and 32 deletions
63
app.py
63
app.py
|
@ -3,6 +3,7 @@ from flask_compress import Compress
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
from mysql.connector import errorcode
|
from mysql.connector import errorcode
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
from werkzeug.utils import secure_filename
|
||||||
import mysql.connector
|
import mysql.connector
|
||||||
import urllib
|
import urllib
|
||||||
import functions as func
|
import functions as func
|
||||||
|
@ -79,7 +80,7 @@ def loginRequired(f):
|
||||||
@wraps(f)
|
@wraps(f)
|
||||||
def login_required(*args, **kwargs):
|
def login_required(*args, **kwargs):
|
||||||
if not logged_in:
|
if not logged_in:
|
||||||
return abort(403)
|
return abort(404)
|
||||||
return f(*args, **kwargs)
|
return f(*args, **kwargs)
|
||||||
return login_required
|
return login_required
|
||||||
|
|
||||||
|
@ -95,6 +96,8 @@ def before_request():
|
||||||
@app.context_processor
|
@app.context_processor
|
||||||
def inject_stuff():
|
def inject_stuff():
|
||||||
cfg = func.loadJSON(const.configFile)
|
cfg = func.loadJSON(const.configFile)
|
||||||
|
# for 1.6.0 or later
|
||||||
|
# questionCount = getQuestionCount()
|
||||||
return dict(metadata=func.generateMetadata(), len=len, str=str, const=const, cfg=cfg, logged_in=logged_in, version_id=const.version_id, version=const.version, appName=const.appName)
|
return dict(metadata=func.generateMetadata(), len=len, str=str, const=const, cfg=cfg, logged_in=logged_in, version_id=const.version_id, version=const.version, appName=const.appName)
|
||||||
|
|
||||||
# -- template filters --
|
# -- template filters --
|
||||||
|
@ -256,7 +259,9 @@ def addQuestion():
|
||||||
return {'error': 'An error has occurred'}, 500
|
return {'error': 'An error has occurred'}, 500
|
||||||
|
|
||||||
blacklist = func.readPlainFile(const.blacklistFile, split=True)
|
blacklist = func.readPlainFile(const.blacklistFile, split=True)
|
||||||
if (question in blacklist) or (from_who in blacklist):
|
|
||||||
|
for bad_word in blacklist:
|
||||||
|
if bad_word in question or bad_word in from_who:
|
||||||
# return a generic error message so bad actors wouldn't figure out the blacklist
|
# return a generic error message so bad actors wouldn't figure out the blacklist
|
||||||
return {'error': 'An error has occurred'}, 500
|
return {'error': 'An error has occurred'}, 500
|
||||||
|
|
||||||
|
@ -309,6 +314,7 @@ def returnToInbox():
|
||||||
return {'message': 'Successfully returned question to inbox.'}, 200
|
return {'message': 'Successfully returned question to inbox.'}, 200
|
||||||
|
|
||||||
@api_bp.route('/pin_question/', methods=['POST'])
|
@api_bp.route('/pin_question/', methods=['POST'])
|
||||||
|
@loginRequired
|
||||||
def pinQuestion():
|
def pinQuestion():
|
||||||
question_id = request.args.get('question_id', '')
|
question_id = request.args.get('question_id', '')
|
||||||
if not question_id:
|
if not question_id:
|
||||||
|
@ -323,6 +329,7 @@ def pinQuestion():
|
||||||
return {'message': 'Successfully pinned question.'}, 200
|
return {'message': 'Successfully pinned question.'}, 200
|
||||||
|
|
||||||
@api_bp.route('/unpin_question/', methods=['POST'])
|
@api_bp.route('/unpin_question/', methods=['POST'])
|
||||||
|
@loginRequired
|
||||||
def unpinQuestion():
|
def unpinQuestion():
|
||||||
question_id = request.args.get('question_id', '')
|
question_id = request.args.get('question_id', '')
|
||||||
if not question_id:
|
if not question_id:
|
||||||
|
@ -363,45 +370,39 @@ def addAnswer():
|
||||||
|
|
||||||
return jsonify({'message': 'Answer added successfully!'}), 201
|
return jsonify({'message': 'Answer added successfully!'}), 201
|
||||||
|
|
||||||
# reserved for 1.6.0 or later
|
@api_bp.route('/upload_favicon/', methods=['POST'])
|
||||||
"""
|
@loginRequired
|
||||||
@api_bp.route('/question_count/', methods=['GET'])
|
def uploadFavicon():
|
||||||
def questionCount():
|
favicon = request.files.get('favicon')
|
||||||
|
|
||||||
|
if favicon and func.allowedFile(favicon.filename):
|
||||||
|
filename = secure_filename(favicon.filename)
|
||||||
|
favicon_path = const.faviconDir / filename
|
||||||
|
favicon.save(favicon_path)
|
||||||
|
|
||||||
|
func.generateFavicon(filename)
|
||||||
|
|
||||||
|
return {'message': 'Successfully updated favicon!'}, 201
|
||||||
|
elif favicon and not func.allowedFile(favicon.filename):
|
||||||
|
return {'error': 'File type is not supported'}, 400
|
||||||
|
elif not favicon:
|
||||||
|
return {'error': "favicon is not specified"}, 400
|
||||||
|
|
||||||
|
@api_bp.route('/get_question_count/', methods=['GET'])
|
||||||
|
def getQuestionCount():
|
||||||
conn = func.connectToDb()
|
conn = func.connectToDb()
|
||||||
cursor = conn.cursor()
|
cursor = conn.cursor()
|
||||||
cursor.execute("SELECT COUNT(*) FROM questions WHERE answered=%s", (False,))
|
cursor.execute("SELECT COUNT(id) FROM questions WHERE answered=%s", (False,))
|
||||||
question_count = cursor.fetchone()
|
question_count = cursor.fetchone()
|
||||||
|
|
||||||
cursor.close()
|
cursor.close()
|
||||||
conn.close()
|
conn.close()
|
||||||
return str(question_count[0])
|
return str(question_count[0])
|
||||||
"""
|
|
||||||
|
|
||||||
# unused
|
# unused
|
||||||
"""
|
"""
|
||||||
@api_bp.route('/all_questions/', methods=['GET'])
|
|
||||||
def listQuestions():
|
|
||||||
answered = request.args.get('answered', False)
|
|
||||||
conn = func.connectToDb()
|
|
||||||
cursor = conn.cursor(dictionary=True)
|
|
||||||
cursor.execute("SELECT id, from_who, creation_date, content, answered, answer_id FROM questions WHERE answered=%s", (answered,))
|
|
||||||
questions = cursor.fetchall()
|
|
||||||
cursor.close()
|
|
||||||
conn.close()
|
|
||||||
return jsonify(questions)
|
|
||||||
|
|
||||||
@api_bp.route('/all_answers/', methods=['GET'])
|
|
||||||
def listAnswers():
|
|
||||||
conn = func.connectToDb()
|
|
||||||
cursor = conn.cursor(dictionary=True)
|
|
||||||
cursor.execute("SELECT id, question_id, creation_date, content FROM answers")
|
|
||||||
answers = cursor.fetchall()
|
|
||||||
cursor.close()
|
|
||||||
conn.close()
|
|
||||||
return jsonify(answers)
|
|
||||||
"""
|
|
||||||
|
|
||||||
@api_bp.route('/view_question/', methods=['GET'])
|
@api_bp.route('/view_question/', methods=['GET'])
|
||||||
|
@loginRequired
|
||||||
def viewQuestion():
|
def viewQuestion():
|
||||||
question_id = request.args.get('question_id', '')
|
question_id = request.args.get('question_id', '')
|
||||||
if not question_id:
|
if not question_id:
|
||||||
|
@ -416,6 +417,7 @@ def viewQuestion():
|
||||||
return jsonify(question)
|
return jsonify(question)
|
||||||
|
|
||||||
@api_bp.route('/view_answer/', methods=['GET'])
|
@api_bp.route('/view_answer/', methods=['GET'])
|
||||||
|
@loginRequired
|
||||||
def viewAnswer():
|
def viewAnswer():
|
||||||
answer_id = request.args.get('answer_id', '')
|
answer_id = request.args.get('answer_id', '')
|
||||||
if not answer_id:
|
if not answer_id:
|
||||||
|
@ -428,6 +430,7 @@ def viewAnswer():
|
||||||
cursor.close()
|
cursor.close()
|
||||||
conn.close()
|
conn.close()
|
||||||
return jsonify(answer)
|
return jsonify(answer)
|
||||||
|
"""
|
||||||
|
|
||||||
@api_bp.route('/update_config/', methods=['POST'])
|
@api_bp.route('/update_config/', methods=['POST'])
|
||||||
@loginRequired
|
@loginRequired
|
||||||
|
|
Loading…
Add table
Reference in a new issue