update
This commit is contained in:
		| @@ -4,4 +4,4 @@ prismic is a simple messageboard made in python | ||||
| ## Planned features | ||||
| - [ ] user board creation | ||||
| - [ ] custom profiles | ||||
| - [ ] moderation tools | ||||
| - [x] moderation tools | ||||
| @@ -405,6 +405,28 @@ class Database: | ||||
|             logger.info("No reference post.") | ||||
|             data['reference'] = None | ||||
|  | ||||
|         # get post references | ||||
|         logger.info(f"Getting post references for post {post[0]}...") | ||||
|         self.cursor.execute(''' | ||||
|             SELECT * FROM posts WHERE refence = ? | ||||
|         ''', (post[0],)) | ||||
|         references = self.cursor.fetchall() | ||||
|  | ||||
|         if references: | ||||
|             data['replies'] = [] | ||||
|             for reference in references: | ||||
|                 reference_data = { | ||||
|                     'id': reference[0], | ||||
|                     'content': reference[3], | ||||
|                     'short_content': reference[3][:20] + '...' if len(reference[3]) > 20 else reference[3], | ||||
|                     'created_at': reference[4] | ||||
|                 } | ||||
|                 data['replies'].append(reference_data) | ||||
|             logger.info(f"Post references found for post {post[0]}.") | ||||
|         else: | ||||
|             logger.warning(f"No post references found for post {post[0]}.") | ||||
|             data['replies'] = [] | ||||
|  | ||||
|         logger.info(f"Post converted to dictionary.") | ||||
|         return data | ||||
|      | ||||
| @@ -540,7 +562,20 @@ class Database: | ||||
|         if boards: | ||||
|             logger.info(f"Boards found.") | ||||
|             # Convert boards to dictionary | ||||
|             boards = [{"id": board[0], "name": board[1]} for board in boards].sort(key=lambda x: x['name']) | ||||
|             boards = [{"id": board[0], "name": board[1]} for board in boards] | ||||
|             boards.sort(key=lambda x: x['name']) | ||||
|             return boards | ||||
|         logger.warning(f"No boards found.") | ||||
|         return None | ||||
|         return None | ||||
|      | ||||
|     def delete_post(self, post_id): | ||||
|         logger.info(f"Deleting post {post_id}...") | ||||
|  | ||||
|         # Delete post | ||||
|         self.cursor.execute(''' | ||||
|             DELETE FROM posts WHERE id = ? | ||||
|         ''', (post_id,)) | ||||
|  | ||||
|         self.connection.commit() | ||||
|         logger.info(f"Post {post_id} deleted.") | ||||
|         return True | ||||
| @@ -33,11 +33,7 @@ | ||||
|         {% block content %}{% endblock %} | ||||
|     </main> | ||||
|     <footer> | ||||
|         <p>Created by <a href="https://alfieking.dev">Alfie King</a> | ||||
|         {% if session.name %} | ||||
|         | <a href="/logout">Logout</a> | ||||
|         {% endif %} | ||||
|         </p> | ||||
|         <p>Created by <a href="https://alfieking.dev">Alfie King</a>{% if session.name %} | <a href="/logout">Logout</a>{% endif %}</p> | ||||
|     </footer> | ||||
| </body> | ||||
| </html> | ||||
| @@ -17,10 +17,12 @@ | ||||
|                 <p>{{ post.short_content }}</p> | ||||
|                 <h6><a href="/posts/{{ post.id }}">View Post</a> | ||||
|                     {% if post.replies|length > 0 %} | ||||
|                      | ({{ post.replies|length }} replies) | ||||
|                      ({{ post.replies|length }} replies) | ||||
|                     {% endif %} | ||||
|                     {% if session.name == "SYSTEM" %} | ||||
|                      | <a href="/delete/post/{{ post.id }}">Delete</a> | ||||
|                     {% elif session.name == post.user.name %} | ||||
|                      | <a href="/delete/post/{{ post.id }}">Delete</a> | ||||
|                     {% endif %} | ||||
|                 </h6> | ||||
|             </li> | ||||
|   | ||||
| @@ -11,15 +11,17 @@ | ||||
|                 <h3>From {{ post.user.name }} in /{{ post.board.name }}/</h3> | ||||
|                 <h6>posted at {{ post.created_at }}</h6> | ||||
|                 {% if post.reference %} | ||||
|                 <h6><b>ref post:</b> <a href="/posts/{{ post.reference.id }}">{{ post.reference.short_content }}</a></h6> | ||||
|                 <h6><b>ref post:</b> <a href="/posts/{{ post.reference.id }}">{{ post.reference.short_content if post.reference.id is not none else '[NOT FOUND]' }}</a></h6> | ||||
|                 {% endif %} | ||||
|                 <p>{{ post.short_content }}</p> | ||||
|                 <h6><a href="/posts/{{ post.id }}">View Post</a> | ||||
|                     {% if post.replies|length > 0 %} | ||||
|                      | ({{ post.replies|length }} replies) | ||||
|                      ({{ post.replies|length }} replies) | ||||
|                     {% endif %} | ||||
|                     {% if session.name == "SYSTEM" %} | ||||
|                      | <a href="/delete/post/{{ post.id }}">Delete</a> | ||||
|                     {% elif session.name == post.user.name %} | ||||
|                      | <a href="/delete/post/{{ post.id }}">Delete</a> | ||||
|                     {% endif %} | ||||
|                 </h6> | ||||
|             </li> | ||||
|   | ||||
| @@ -7,8 +7,15 @@ | ||||
|     <h6><b>ref post:</b> <a href="/posts/{{ post.reference.id }}">{{ post.reference.content }}</a></h6> | ||||
|     {% endif %} | ||||
|     <p>{{ post.content }}</p> | ||||
|     {% if session.name == "SYSTEM" %} | ||||
|     <h6><a href="/delete/post/{{ post.id }}">Delete</a></h6> | ||||
|     {% elif session.name == post.user.name %} | ||||
|     <h6><a href="/delete/post/{{ post.id }}">Delete</a></h6> | ||||
|     {% endif %} | ||||
|     <br> | ||||
|  | ||||
|     <h3>Replies:</h3> | ||||
|      | ||||
|     <ul class="posts"> | ||||
|         {% for reply in post.replies %} | ||||
|             <li> | ||||
| @@ -16,11 +23,10 @@ | ||||
|                 <h6>posted at {{ reply.created_at }}</h6> | ||||
|                 <p>{{ reply.short_content }}</p> | ||||
|                 <h6><a href="/posts/{{ reply.id }}">View Reply</a> | ||||
|                     {% if post.replies|length > 0 %} | ||||
|                      | ({{ post.replies|length }} replies) | ||||
|                     {% endif %} | ||||
|                     {% if session.name == "SYSTEM" %} | ||||
|                      | <a href="/delete/post/{{ post.id }}">Delete</a> | ||||
|                      | <a href="/delete/post/{{ reply.id }}">Delete</a> | ||||
|                     {% elif session.name == post.user.name %} | ||||
|                      | <a href="/delete/post/{{ reply.id }}">Delete</a> | ||||
|                     {% endif %} | ||||
|                 </h6> | ||||
|             </li> | ||||
|   | ||||
| @@ -15,10 +15,12 @@ | ||||
|                 <p>{{ post.short_content }}</p> | ||||
|                 <h6><a href="/posts/{{ post.id }}">View post</a> | ||||
|                     {% if post.replies|length > 0 %} | ||||
|                      | ({{ post.replies|length }} replies) | ||||
|                      ({{ post.replies|length }} replies) | ||||
|                     {% endif %} | ||||
|                     {% if session.name == "SYSTEM" %} | ||||
|                      | <a href="/delete/post/{{ post.id }}">Delete</a> | ||||
|                     {% elif session.name == post.user.name %} | ||||
|                      | <a href="/delete/post/{{ post.id }}">Delete</a> | ||||
|                     {% endif %} | ||||
|                 </h6> | ||||
|             </li> | ||||
|   | ||||
| @@ -14,7 +14,16 @@ | ||||
|                 <h6><b>ref post:</b> <a href="/posts/{{ post.reference.id }}">{{ post.reference.content }}</a></h6> | ||||
|                 {% endif %} | ||||
|                 <p>{{ post.content }}</p> | ||||
|                 <h6><a href="/posts/{{ post.id }}">View Post</a></h6> | ||||
|                 <h6><a href="/posts/{{ post.id }}">View Post</a> | ||||
|                     {% if post.replies|length > 0 %} | ||||
|                     ({{ post.replies|length }} replies) | ||||
|                     {% endif %} | ||||
|                     {% if session.name == "SYSTEM" %} | ||||
|                      | <a href="/delete/post/{{ post.id }}">Delete</a> | ||||
|                     {% elif session.name == post.user.name %} | ||||
|                      | <a href="/delete/post/{{ post.id }}">Delete</a> | ||||
|                     {% endif %} | ||||
|                 </h6> | ||||
|             </li> | ||||
|         {% endfor %} | ||||
|         {% if user.posts|length == 0 %} | ||||
|   | ||||
							
								
								
									
										82
									
								
								src/main.py
									
									
									
									
									
								
							
							
						
						
									
										82
									
								
								src/main.py
									
									
									
									
									
								
							| @@ -16,6 +16,29 @@ logger.addHandler(console_log) | ||||
| logger.setLevel(logging.INFO) | ||||
|  | ||||
|  | ||||
| # Helper functions | ||||
| def sanitize_input(input_string): | ||||
|     logger.info("Sanitizing input...") | ||||
|     # Sanitize input to allow only certain characters | ||||
|     if not isinstance(input_string, str): | ||||
|         logger.error("Input is not a string.") | ||||
|         return None | ||||
|     sanitized = ''.join(c for c in input_string if c in ALLOWED_CHARS) | ||||
|     logger.info("Sanitized input") | ||||
|     return sanitized | ||||
|  | ||||
|  | ||||
| def hash_password(password): | ||||
|     logger.info("Hashing password...") | ||||
|     # Hash the password using SHA-256 | ||||
|     if not isinstance(password, str): | ||||
|         logger.error("Password is not a string.") | ||||
|         return None | ||||
|     hashed = hashlib.sha256(password.encode()).hexdigest() | ||||
|     logger.info("Hashed password") | ||||
|     return hashed | ||||
|  | ||||
|  | ||||
| # Initialize Flask app | ||||
| logger.info("Initializing Flask app...") | ||||
| app = Flask(__name__, template_folder=os.getenv('TEMPLATE_FOLDER', 'html'), static_folder=os.getenv('STATIC_FOLDER', 'static')) | ||||
| @@ -33,7 +56,11 @@ if db.get_user('SYSTEM') is None: | ||||
|     logger.info("Running first time setup...") | ||||
|  | ||||
|     logger.info("Creating SYSTEM user...") | ||||
|     db.create_user('SYSTEM', 'SYSTEM') | ||||
|     password = os.getenv('SYSTEM_PASSWORD', None) | ||||
|     if password is None: | ||||
|         password = os.urandom(16).hex() | ||||
|     logger.info("Generated password for SYSTEM user: %s", password) | ||||
|     db.create_user('SYSTEM', hash_password(password)) | ||||
|     SYSTEMUID = db.get_user('SYSTEM')[0] | ||||
|     logger.info("SYSTEM user created with UID: %s", SYSTEMUID) | ||||
|  | ||||
| @@ -61,30 +88,6 @@ else: | ||||
| logger.info("Database initialized.") | ||||
|  | ||||
|  | ||||
| # Helper functions | ||||
|  | ||||
| def sanitize_input(input_string): | ||||
|     logger.info("Sanitizing input...") | ||||
|     # Sanitize input to allow only certain characters | ||||
|     if not isinstance(input_string, str): | ||||
|         logger.error("Input is not a string.") | ||||
|         return None | ||||
|     sanitized = ''.join(c for c in input_string if c in ALLOWED_CHARS) | ||||
|     logger.info("Sanitized input") | ||||
|     return sanitized | ||||
|  | ||||
|  | ||||
| def hash_password(password): | ||||
|     logger.info("Hashing password...") | ||||
|     # Hash the password using SHA-256 | ||||
|     if not isinstance(password, str): | ||||
|         logger.error("Password is not a string.") | ||||
|         return None | ||||
|     hashed = hashlib.sha256(password.encode()).hexdigest() | ||||
|     logger.info("Hashed password") | ||||
|     return hashed | ||||
|  | ||||
|  | ||||
| # Define routes | ||||
| @app.route('/') | ||||
| def index(): | ||||
| @@ -337,6 +340,35 @@ def register(): | ||||
|     return render_template('register.html') | ||||
|  | ||||
|  | ||||
| @app.route('/delete/post/<int:post_id>', methods=['GET']) | ||||
| def delete_post(post_id): | ||||
|     logger.info("Deleting post ID: %s", post_id) | ||||
|     token = session.get('session') | ||||
|     if not token: | ||||
|         logger.error("Session token is missing.") | ||||
|         return "Session expired. Please log in again.", 403 | ||||
|  | ||||
|     user = db.get_session(token) | ||||
|     if user is None: | ||||
|         logger.error("Session not found or expired.") | ||||
|         return "Session expired. Please log in again.", 403 | ||||
|  | ||||
|     user_id = user[0] | ||||
|     post = db.get_post(post_id) | ||||
|     if post is None: | ||||
|         logger.error("Post not found: %s", post_id) | ||||
|         return "Post not found", 404 | ||||
|  | ||||
|     if post[1] != user_id and user_id != SYSTEMUID: | ||||
|         logger.error("User %s is not allowed to delete this post.", user_id) | ||||
|         return "You are not allowed to delete this post.", 403 | ||||
|  | ||||
|     db.delete_post(post_id) | ||||
|     logger.info("Post ID %s deleted successfully.", post_id) | ||||
|  | ||||
|     return redirect('/posts') | ||||
|  | ||||
|  | ||||
| # Main function | ||||
| if __name__ == '__main__': | ||||
|     logger.info("Starting Flask app...") | ||||
|   | ||||
		Reference in New Issue
	
	Block a user