171 lines
4.9 KiB
Python
171 lines
4.9 KiB
Python
import jwt as pyjwt
|
|
import datetime
|
|
import bcrypt
|
|
import psycopg2
|
|
import psycopg2.extras
|
|
from flask import Flask, request, jsonify
|
|
import os
|
|
from dotenv import load_dotenv
|
|
|
|
# Flask App erstellen
|
|
app = Flask(__name__)
|
|
app.config['SECRET_KEY'] = 'supergeheimeschluessel'
|
|
|
|
# .env-Datei laden
|
|
load_dotenv()
|
|
|
|
# Zugriff auf die Umgebungsvariablen
|
|
DB_HOST = os.getenv("DB_HOST")
|
|
DB_PORT = os.getenv("DB_PORT")
|
|
DB_NAME = os.getenv("DB_NAME")
|
|
DB_USER = os.getenv("DB_USER")
|
|
DB_PASSWORD = os.getenv("DB_PASSWORD")
|
|
|
|
# Verbindung zur PostgreSQL-Datenbank herstellen
|
|
def connect_db():
|
|
return psycopg2.connect(
|
|
dbname=DB_NAME,
|
|
user=DB_USER,
|
|
password=DB_PASSWORD,
|
|
host=DB_HOST,
|
|
port=DB_PORT
|
|
)
|
|
|
|
def create_tables():
|
|
conn = connect_db()
|
|
cur = conn.cursor()
|
|
cur.execute('''
|
|
CREATE TABLE IF NOT EXISTS users (
|
|
id SERIAL PRIMARY KEY,
|
|
username TEXT UNIQUE NOT NULL,
|
|
password TEXT NOT NULL,
|
|
is_active BOOLEAN DEFAULT TRUE,
|
|
email TEXT UNIQUE NOT NULL,
|
|
reset_password_token TEXT,
|
|
reset_password_expires TIMESTAMP
|
|
);
|
|
''')
|
|
conn.commit()
|
|
cur.close()
|
|
conn.close()
|
|
|
|
def generate_jwt(user_id):
|
|
payload = {
|
|
'user_id': user_id,
|
|
'exp': datetime.datetime.utcnow() + datetime.timedelta(hours=1)
|
|
}
|
|
return pyjwt.encode(payload, app.config['SECRET_KEY'], algorithm='HS256')
|
|
|
|
def verify_jwt(token):
|
|
try:
|
|
payload = pyjwt.decode(token, app.config['SECRET_KEY'], algorithms=['HS256'])
|
|
return payload['user_id']
|
|
except pyjwt.ExpiredSignatureError:
|
|
return None
|
|
except pyjwt.InvalidTokenError:
|
|
return None
|
|
|
|
def hash_password(password):
|
|
return bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
|
|
|
|
def check_password(password, hashed):
|
|
return bcrypt.checkpw(password.encode('utf-8'), hashed.encode('utf-8'))
|
|
|
|
@app.route('/register', methods=['POST'])
|
|
def register():
|
|
data = request.json
|
|
username = data.get('username')
|
|
email = data.get('email')
|
|
password = data.get('password')
|
|
|
|
if not username or not email or not password:
|
|
return jsonify({'error': 'Alle Felder erforderlich'}), 400
|
|
|
|
hashed_password = hash_password(password)
|
|
|
|
conn = connect_db()
|
|
cur = conn.cursor()
|
|
try:
|
|
cur.execute("INSERT INTO users (username, email, password) VALUES (%s, %s, %s) RETURNING id", (username, email, hashed_password))
|
|
user_id = cur.fetchone()[0]
|
|
conn.commit()
|
|
except psycopg2.IntegrityError:
|
|
return jsonify({'error': 'Benutzername oder E-Mail bereits vergeben'}), 400
|
|
finally:
|
|
cur.close()
|
|
conn.close()
|
|
|
|
return jsonify({'message': 'Benutzer registriert', 'user_id': user_id})
|
|
|
|
@app.route('/login', methods=['POST'])
|
|
def login():
|
|
data = request.json
|
|
username = data.get('username')
|
|
password = data.get('password')
|
|
|
|
conn = connect_db()
|
|
cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
|
|
cur.execute("SELECT * FROM users WHERE username = %s", (username,))
|
|
user = cur.fetchone()
|
|
cur.close()
|
|
conn.close()
|
|
|
|
if not user or not check_password(password, user['password']):
|
|
return jsonify({'error': 'Ungültige Anmeldeinformationen'}), 401
|
|
|
|
token = generate_jwt(user['id'])
|
|
return jsonify({'token': token})
|
|
|
|
@app.route('/kasse', methods=['GET'])
|
|
def get_kasse():
|
|
token = request.headers.get('Authorization')
|
|
if not token:
|
|
return jsonify({'error': 'Kein Token vorhanden'}), 401
|
|
|
|
user_id = verify_jwt(token.split()[1])
|
|
if not user_id:
|
|
return jsonify({'error': 'Ungültiges Token'}), 401
|
|
|
|
conn = connect_db()
|
|
cur = conn.cursor(cursor_factory=psycopg2.extras.DictCursor)
|
|
cur.execute("SELECT * FROM kasse ORDER BY timestamp DESC")
|
|
rows = cur.fetchall()
|
|
cur.close()
|
|
conn.close()
|
|
|
|
return jsonify([dict(row) for row in rows])
|
|
|
|
@app.route('/new_entry', methods=['POST'])
|
|
def new_entry():
|
|
token = request.headers.get('Authorization')
|
|
if not token:
|
|
return jsonify({'error': 'Kein Token vorhanden'}), 401
|
|
|
|
user_id = verify_jwt(token.split()[1])
|
|
if not user_id:
|
|
return jsonify({'error': 'Ungültiges Token'}), 401
|
|
|
|
data = request.json
|
|
beschreibung = data.get('beschreibung')
|
|
wert = data.get('wert')
|
|
typ = data.get('typ')
|
|
bar = data.get('bar')
|
|
|
|
if not beschreibung or wert is None or not typ or bar is None:
|
|
return jsonify({'error': 'Alle Felder erforderlich'}), 400
|
|
|
|
conn = connect_db()
|
|
cur = conn.cursor()
|
|
cur.execute("INSERT INTO kasse (beschreibung, wert, typ, bar) VALUES (%s, %s, %s, %s) RETURNING id",
|
|
(beschreibung, wert, typ, bar))
|
|
entry_id = cur.fetchone()[0]
|
|
conn.commit()
|
|
cur.close()
|
|
conn.close()
|
|
|
|
return jsonify({'message': 'Eintrag erstellt', 'entry_id': entry_id})
|
|
|
|
if __name__ == '__main__':
|
|
create_tables()
|
|
app.run(debug=True)
|