From fd7bc598515f24d9d4cc310303803368e798b565 Mon Sep 17 00:00:00 2001 From: marwin Date: Sun, 20 Apr 2025 19:58:27 +0100 Subject: [PATCH] Add user authentication routes: implement login, registration, and logout functionality, along with user profile and admin routes. Enhance mindmap API with error handling and default node creation. --- website/app.py | 415 +++++++++++++++++++++++-------------------------- 1 file changed, 198 insertions(+), 217 deletions(-) diff --git a/website/app.py b/website/app.py index 65c2444..ba49a57 100644 --- a/website/app.py +++ b/website/app.py @@ -31,6 +31,204 @@ def create_app(): except Exception as e: print(f"Error initializing database: {str(e)}") + # Register all routes with the app + @login_manager.user_loader + def load_user(id): + return User.query.get(int(id)) + + @app.route('/login', methods=['GET', 'POST']) + def login(): + if request.method == 'POST': + username = request.form.get('username') + password = request.form.get('password') + + user = User.query.filter_by(username=username).first() + if user and user.check_password(password): + login_user(user) + next_page = request.args.get('next') + return redirect(next_page or url_for('index')) + flash('Ungültiger Benutzername oder Passwort') + return render_template('login.html') + + @app.route('/register', methods=['GET', 'POST']) + def register(): + if request.method == 'POST': + username = request.form.get('username') + email = request.form.get('email') + password = request.form.get('password') + + if User.query.filter_by(username=username).first(): + flash('Benutzername existiert bereits') + return redirect(url_for('register')) + + if User.query.filter_by(email=email).first(): + flash('E-Mail ist bereits registriert') + return redirect(url_for('register')) + + user = User(username=username, email=email) + user.set_password(password) + db.session.add(user) + db.session.commit() + + login_user(user) + return redirect(url_for('index')) + return render_template('register.html') + + @app.route('/logout') + @login_required + def logout(): + logout_user() + return redirect(url_for('index')) + + @app.route('/') + def index(): + return render_template('index.html') + + @app.route('/mindmap') + def mindmap(): + try: + root_node = MindMapNode.query.filter_by(parent_id=None).first() + if not root_node: + root_node = MindMapNode(name="Wissenschaft") + db.session.add(root_node) + db.session.commit() + return render_template('mindmap.html') + except Exception as e: + app.logger.error(f"Error loading mindmap: {str(e)}") + return render_template('mindmap.html', error="Fehler beim Laden der Mindmap. Bitte versuchen Sie es erneut.") + + @app.route('/profile') + @login_required + def profile(): + thoughts = Thought.query.filter_by(user_id=current_user.id).order_by(Thought.timestamp.desc()).all() + return render_template('profile.html', thoughts=thoughts) + + @app.route('/api/mindmap') + def get_mindmap(): + try: + root_nodes = MindMapNode.query.filter_by(parent_id=None).all() + + def build_tree(node): + return { + 'id': node.id, + 'name': node.name, + 'children': [build_tree(child) for child in node.children] + } + + result = [build_tree(node) for node in root_nodes] + if not result: + root = MindMapNode(name="Wissenschaft") + db.session.add(root) + db.session.commit() + result = [build_tree(root)] + + return jsonify(result) + except Exception as e: + app.logger.error(f"Error in get_mindmap: {str(e)}") + return jsonify({'error': 'Fehler beim Laden der Mindmap'}), 500 + + @app.route('/api/thoughts/', methods=['GET']) + def get_thoughts(node_id): + node = MindMapNode.query.get_or_404(node_id) + thoughts = [] + + for thought in node.thoughts: + thoughts.append({ + 'id': thought.id, + 'content': thought.content, + 'author': thought.author.username, + 'timestamp': thought.timestamp.strftime('%d.%m.%Y, %H:%M'), + 'comments_count': len(thought.comments), + 'branch': thought.branch + }) + + return jsonify(thoughts) + + @app.route('/api/thoughts', methods=['POST']) + @login_required + def add_thought(): + data = request.json + node_id = data.get('node_id') + content = data.get('content') + + if not node_id or not content: + return jsonify({'error': 'Fehlende Daten'}), 400 + + node = MindMapNode.query.get_or_404(node_id) + + thought = Thought( + content=content, + branch=node.name, + user_id=current_user.id + ) + + db.session.add(thought) + node.thoughts.append(thought) + db.session.commit() + + return jsonify({ + 'id': thought.id, + 'content': thought.content, + 'author': thought.author.username, + 'timestamp': thought.timestamp.strftime('%d.%m.%Y, %H:%M'), + 'branch': thought.branch + }) + + @app.route('/api/comments/', methods=['GET']) + def get_comments(thought_id): + thought = Thought.query.get_or_404(thought_id) + comments = [ + { + 'id': comment.id, + 'content': comment.content, + 'author': comment.author.username, + 'timestamp': comment.timestamp.strftime('%d.%m.%Y, %H:%M') + } + for comment in thought.comments + ] + return jsonify(comments) + + @app.route('/api/comments', methods=['POST']) + @login_required + def add_comment(): + data = request.json + thought_id = data.get('thought_id') + content = data.get('content') + + if not thought_id or not content: + return jsonify({'error': 'Fehlende Daten'}), 400 + + thought = Thought.query.get_or_404(thought_id) + + comment = Comment( + content=content, + thought_id=thought_id, + user_id=current_user.id + ) + + db.session.add(comment) + db.session.commit() + + return jsonify({ + 'id': comment.id, + 'content': comment.content, + 'author': comment.author.username, + 'timestamp': comment.timestamp.strftime('%d.%m.%Y, %H:%M') + }) + + @app.route('/admin') + @login_required + def admin(): + if not current_user.is_admin: + flash('Zugriff verweigert') + return redirect(url_for('index')) + + users = User.query.all() + nodes = MindMapNode.query.all() + thoughts = Thought.query.all() + + return render_template('admin.html', users=users, nodes=nodes, thoughts=thoughts) + return app # Database Models @@ -77,223 +275,6 @@ node_thought_association = db.Table('node_thought_association', db.Column('thought_id', db.Integer, db.ForeignKey('thought.id'), primary_key=True) ) -@login_manager.user_loader -def load_user(id): - return User.query.get(int(id)) - -# Routes for authentication -@app.route('/login', methods=['GET', 'POST']) -def login(): - if request.method == 'POST': - username = request.form.get('username') - password = request.form.get('password') - - user = User.query.filter_by(username=username).first() - if user and user.check_password(password): - login_user(user) - next_page = request.args.get('next') - return redirect(next_page or url_for('index')) - flash('Ungültiger Benutzername oder Passwort') - return render_template('login.html') - -@app.route('/register', methods=['GET', 'POST']) -def register(): - if request.method == 'POST': - username = request.form.get('username') - email = request.form.get('email') - password = request.form.get('password') - - if User.query.filter_by(username=username).first(): - flash('Benutzername existiert bereits') - return redirect(url_for('register')) - - if User.query.filter_by(email=email).first(): - flash('E-Mail ist bereits registriert') - return redirect(url_for('register')) - - user = User(username=username, email=email) - user.set_password(password) - db.session.add(user) - db.session.commit() - - login_user(user) - return redirect(url_for('index')) - return render_template('register.html') - -@app.route('/logout') -@login_required -def logout(): - logout_user() - return redirect(url_for('index')) - -# Route for the homepage -@app.route('/') -def index(): - return render_template('index.html') - -# Route for the mindmap page -@app.route('/mindmap') -def mindmap(): - try: - root_node = MindMapNode.query.filter_by(parent_id=None).first() - if not root_node: - root_node = MindMapNode(name="Wissenschaft") - db.session.add(root_node) - db.session.commit() - return render_template('mindmap.html') - except Exception as e: - app.logger.error(f"Error loading mindmap: {str(e)}") - return render_template('mindmap.html', error="Fehler beim Laden der Mindmap. Bitte versuchen Sie es erneut.") - -# Route for user profile -@app.route('/profile') -@login_required -def profile(): - thoughts = Thought.query.filter_by(user_id=current_user.id).order_by(Thought.timestamp.desc()).all() - return render_template('profile.html', thoughts=thoughts) - -# API routes for mindmap and thoughts -@app.route('/api/mindmap') -def get_mindmap(): - try: - root_nodes = MindMapNode.query.filter_by(parent_id=None).all() - - def build_tree(node): - return { - 'id': node.id, - 'name': node.name, - 'children': [build_tree(child) for child in node.children] - } - - result = [build_tree(node) for node in root_nodes] - if not result: - # Create default root if no nodes exist - root = MindMapNode(name="Wissenschaft") - db.session.add(root) - db.session.commit() - result = [build_tree(root)] - - return jsonify(result) - except Exception as e: - app.logger.error(f"Error in get_mindmap: {str(e)}") - return jsonify({'error': 'Fehler beim Laden der Mindmap'}), 500 - -@app.route('/api/thoughts/', methods=['GET']) -def get_thoughts(node_id): - node = MindMapNode.query.get_or_404(node_id) - thoughts = [] - - for thought in node.thoughts: - thoughts.append({ - 'id': thought.id, - 'content': thought.content, - 'author': thought.author.username, - 'timestamp': thought.timestamp.strftime('%d.%m.%Y, %H:%M'), - 'comments_count': len(thought.comments), - 'branch': thought.branch - }) - - return jsonify(thoughts) - -@app.route('/api/thought/', methods=['GET']) -def get_thought(thought_id): - thought = Thought.query.get_or_404(thought_id) - - return jsonify({ - 'id': thought.id, - 'content': thought.content, - 'author': thought.author.username, - 'timestamp': thought.timestamp.strftime('%d.%m.%Y, %H:%M'), - 'branch': thought.branch, - 'comments_count': len(thought.comments) - }) - -@app.route('/api/thoughts', methods=['POST']) -@login_required -def add_thought(): - data = request.json - node_id = data.get('node_id') - content = data.get('content') - - if not node_id or not content: - return jsonify({'error': 'Fehlende Daten'}), 400 - - node = MindMapNode.query.get_or_404(node_id) - - thought = Thought( - content=content, - branch=node.name, - user_id=current_user.id - ) - - db.session.add(thought) - node.thoughts.append(thought) - db.session.commit() - - return jsonify({ - 'id': thought.id, - 'content': thought.content, - 'author': thought.author.username, - 'timestamp': thought.timestamp.strftime('%d.%m.%Y, %H:%M'), - 'branch': thought.branch - }) - -@app.route('/api/comments/', methods=['GET']) -def get_comments(thought_id): - thought = Thought.query.get_or_404(thought_id) - comments = [ - { - 'id': comment.id, - 'content': comment.content, - 'author': comment.author.username, - 'timestamp': comment.timestamp.strftime('%d.%m.%Y, %H:%M') - } - for comment in thought.comments - ] - return jsonify(comments) - -@app.route('/api/comments', methods=['POST']) -@login_required -def add_comment(): - data = request.json - thought_id = data.get('thought_id') - content = data.get('content') - - if not thought_id or not content: - return jsonify({'error': 'Fehlende Daten'}), 400 - - thought = Thought.query.get_or_404(thought_id) - - comment = Comment( - content=content, - thought_id=thought_id, - user_id=current_user.id - ) - - db.session.add(comment) - db.session.commit() - - return jsonify({ - 'id': comment.id, - 'content': comment.content, - 'author': comment.author.username, - 'timestamp': comment.timestamp.strftime('%d.%m.%Y, %H:%M') - }) - -# Admin routes -@app.route('/admin') -@login_required -def admin(): - if not current_user.is_admin: - flash('Zugriff verweigert') - return redirect(url_for('index')) - - users = User.query.all() - nodes = MindMapNode.query.all() - thoughts = Thought.query.all() - - return render_template('admin.html', users=users, nodes=nodes, thoughts=thoughts) - if __name__ == '__main__': app = create_app() app.run(host="0.0.0.0", port=6000, debug=True) \ No newline at end of file