This commit is contained in:
Alfie King 2025-04-22 15:37:22 +01:00
parent 9760fc88e4
commit e9dc5e5056
9 changed files with 126 additions and 42 deletions

View File

@ -4,4 +4,4 @@ prismic is a simple messageboard made in python
## Planned features
- [ ] user board creation
- [ ] custom profiles
- [ ] moderation tools
- [x] moderation tools

View File

@ -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

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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 %}

View File

@ -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...")