Search code examples
python-3.xflaskflask-wtformswtformskeepass

Flask app fails to load keepass file after a certain amount of time, when deployed as a service on centos7


I have a flask web app deployed on one of the internal servers of the organization where I work. I developed a number of simple automation tools that is used by the IT team, and I made them available through this app. I am having an issue that I can't figure out, when I try to include a new tool in the app. This new tool is supposed to connect to a selected database host where it runs an SQL script to determine if there are any bloated tables present (postgres). Originally, I made a CLI tool to do this, but I thought it would be nice to have it deployed for everyone on the team to use, so I added this to the existing flask app. I made a simplified version of this part of the code.

FLASK:

from flask import Flask, render_template
from flask_wtf import FlaskForm
from wtforms import SubmitField, PasswordField
from wtforms.validators import ValidationError
from pykeepass import PyKeePass

app = Flask(__name__)
app.config['SECRET_KEY'] = '\xaa_:P\xcd4X\xf7\xebAA\x07=,\x8f\n&\xac\xc8\xc8\xa8}\x13P'

def validate_password(form, field):
    try:
        kp = PyKeePass('example_keepass_file.kdbx', password=field.data)
    except Exception:
        raise ValidationError('Incorrect password')
    
class Bloatform(FlaskForm):
    password = PasswordField('Keepass file password', validators=[validate_password])
    submit = SubmitField('Submit')

@app.route('/', methods=['GET', 'POST'])
def index():
    form = Bloatform()
    if form.validate_on_submit():
        pass
    return render_template('example.html', form=form)

if __name__ == '__main__':
    app.run(host='0.0.0.0')

HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Example</title>
</head>
<body>
    <form method="POST" action="">
        {{ form.csrf_token }}
        {{ form.password.label }}
        {% if form.password.errors %}
            {{ form.password }}
            <div>
                {% for error in form.password.errors %}
                    <span>{{ error }}</span>
                {% endfor %}
            </div>
        {% else %}
            {{ form.password }}
        {% endif %}
        <div >
            {{ form.submit }}
        </div>
</body>
</html>

This all works great, the password is validated and if it is correct, the script does its thing. If the password provided in the form is not correct, it gives a validationerror as it should. However, when I try to use the tool the next day, I get a validationerror (Incorrect Password) even if the password is correct. Looks like something is timing out here but I don't know what... Only 'systemctl restart flask' fixes the issue, which is not ideal as I am not looking to start my day everyday with restarting the app. Tried to look into the pykeepass documentation, searched some threads for similar issues, but couldn't find a solution anywhere. I deployed the app on the server using this tutorial (with a few minor changes):

tutorial

Please note there are other 3 tools deployed here that have no issues at all, so I am suspecting there is something with the pykeepass module itself.

Python version: 3.8

pykeepass: 4.0.3

Any help is appreciated, thanks in advance!


Solution

  • I stopped using PyKeepass, and went with an sqlite implementation instead. The issue is no longer present.