update
This commit is contained in:
		@@ -4,4 +4,4 @@ prismic is a simple messageboard made in python
 | 
				
			|||||||
## Planned features
 | 
					## Planned features
 | 
				
			||||||
- [ ] user board creation
 | 
					- [ ] user board creation
 | 
				
			||||||
- [ ] custom profiles
 | 
					- [ ] custom profiles
 | 
				
			||||||
- [ ] moderation tools
 | 
					- [x] moderation tools
 | 
				
			||||||
@@ -405,6 +405,28 @@ class Database:
 | 
				
			|||||||
            logger.info("No reference post.")
 | 
					            logger.info("No reference post.")
 | 
				
			||||||
            data['reference'] = None
 | 
					            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.")
 | 
					        logger.info(f"Post converted to dictionary.")
 | 
				
			||||||
        return data
 | 
					        return data
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
@@ -540,7 +562,20 @@ class Database:
 | 
				
			|||||||
        if boards:
 | 
					        if boards:
 | 
				
			||||||
            logger.info(f"Boards found.")
 | 
					            logger.info(f"Boards found.")
 | 
				
			||||||
            # Convert boards to dictionary
 | 
					            # 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
 | 
					            return boards
 | 
				
			||||||
        logger.warning(f"No boards found.")
 | 
					        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 %}
 | 
					        {% block content %}{% endblock %}
 | 
				
			||||||
    </main>
 | 
					    </main>
 | 
				
			||||||
    <footer>
 | 
					    <footer>
 | 
				
			||||||
        <p>Created by <a href="https://alfieking.dev">Alfie King</a>
 | 
					        <p>Created by <a href="https://alfieking.dev">Alfie King</a>{% if session.name %} | <a href="/logout">Logout</a>{% endif %}</p>
 | 
				
			||||||
        {% if session.name %}
 | 
					 | 
				
			||||||
        | <a href="/logout">Logout</a>
 | 
					 | 
				
			||||||
        {% endif %}
 | 
					 | 
				
			||||||
        </p>
 | 
					 | 
				
			||||||
    </footer>
 | 
					    </footer>
 | 
				
			||||||
</body>
 | 
					</body>
 | 
				
			||||||
</html>
 | 
					</html>
 | 
				
			||||||
@@ -17,10 +17,12 @@
 | 
				
			|||||||
                <p>{{ post.short_content }}</p>
 | 
					                <p>{{ post.short_content }}</p>
 | 
				
			||||||
                <h6><a href="/posts/{{ post.id }}">View Post</a>
 | 
					                <h6><a href="/posts/{{ post.id }}">View Post</a>
 | 
				
			||||||
                    {% if post.replies|length > 0 %}
 | 
					                    {% if post.replies|length > 0 %}
 | 
				
			||||||
                     | ({{ post.replies|length }} replies)
 | 
					                     ({{ post.replies|length }} replies)
 | 
				
			||||||
                    {% endif %}
 | 
					                    {% endif %}
 | 
				
			||||||
                    {% if session.name == "SYSTEM" %}
 | 
					                    {% if session.name == "SYSTEM" %}
 | 
				
			||||||
                     | <a href="/delete/post/{{ post.id }}">Delete</a>
 | 
					                     | <a href="/delete/post/{{ post.id }}">Delete</a>
 | 
				
			||||||
 | 
					                    {% elif session.name == post.user.name %}
 | 
				
			||||||
 | 
					                     | <a href="/delete/post/{{ post.id }}">Delete</a>
 | 
				
			||||||
                    {% endif %}
 | 
					                    {% endif %}
 | 
				
			||||||
                </h6>
 | 
					                </h6>
 | 
				
			||||||
            </li>
 | 
					            </li>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,15 +11,17 @@
 | 
				
			|||||||
                <h3>From {{ post.user.name }} in /{{ post.board.name }}/</h3>
 | 
					                <h3>From {{ post.user.name }} in /{{ post.board.name }}/</h3>
 | 
				
			||||||
                <h6>posted at {{ post.created_at }}</h6>
 | 
					                <h6>posted at {{ post.created_at }}</h6>
 | 
				
			||||||
                {% if post.reference %}
 | 
					                {% 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 %}
 | 
					                {% endif %}
 | 
				
			||||||
                <p>{{ post.short_content }}</p>
 | 
					                <p>{{ post.short_content }}</p>
 | 
				
			||||||
                <h6><a href="/posts/{{ post.id }}">View Post</a>
 | 
					                <h6><a href="/posts/{{ post.id }}">View Post</a>
 | 
				
			||||||
                    {% if post.replies|length > 0 %}
 | 
					                    {% if post.replies|length > 0 %}
 | 
				
			||||||
                     | ({{ post.replies|length }} replies)
 | 
					                     ({{ post.replies|length }} replies)
 | 
				
			||||||
                    {% endif %}
 | 
					                    {% endif %}
 | 
				
			||||||
                    {% if session.name == "SYSTEM" %}
 | 
					                    {% if session.name == "SYSTEM" %}
 | 
				
			||||||
                     | <a href="/delete/post/{{ post.id }}">Delete</a>
 | 
					                     | <a href="/delete/post/{{ post.id }}">Delete</a>
 | 
				
			||||||
 | 
					                    {% elif session.name == post.user.name %}
 | 
				
			||||||
 | 
					                     | <a href="/delete/post/{{ post.id }}">Delete</a>
 | 
				
			||||||
                    {% endif %}
 | 
					                    {% endif %}
 | 
				
			||||||
                </h6>
 | 
					                </h6>
 | 
				
			||||||
            </li>
 | 
					            </li>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,8 +7,15 @@
 | 
				
			|||||||
    <h6><b>ref post:</b> <a href="/posts/{{ post.reference.id }}">{{ post.reference.content }}</a></h6>
 | 
					    <h6><b>ref post:</b> <a href="/posts/{{ post.reference.id }}">{{ post.reference.content }}</a></h6>
 | 
				
			||||||
    {% endif %}
 | 
					    {% endif %}
 | 
				
			||||||
    <p>{{ post.content }}</p>
 | 
					    <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>
 | 
					    <br>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    <h3>Replies:</h3>
 | 
					    <h3>Replies:</h3>
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    <ul class="posts">
 | 
					    <ul class="posts">
 | 
				
			||||||
        {% for reply in post.replies %}
 | 
					        {% for reply in post.replies %}
 | 
				
			||||||
            <li>
 | 
					            <li>
 | 
				
			||||||
@@ -16,11 +23,10 @@
 | 
				
			|||||||
                <h6>posted at {{ reply.created_at }}</h6>
 | 
					                <h6>posted at {{ reply.created_at }}</h6>
 | 
				
			||||||
                <p>{{ reply.short_content }}</p>
 | 
					                <p>{{ reply.short_content }}</p>
 | 
				
			||||||
                <h6><a href="/posts/{{ reply.id }}">View Reply</a>
 | 
					                <h6><a href="/posts/{{ reply.id }}">View Reply</a>
 | 
				
			||||||
                    {% if post.replies|length > 0 %}
 | 
					 | 
				
			||||||
                     | ({{ post.replies|length }} replies)
 | 
					 | 
				
			||||||
                    {% endif %}
 | 
					 | 
				
			||||||
                    {% if session.name == "SYSTEM" %}
 | 
					                    {% 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 %}
 | 
					                    {% endif %}
 | 
				
			||||||
                </h6>
 | 
					                </h6>
 | 
				
			||||||
            </li>
 | 
					            </li>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,10 +15,12 @@
 | 
				
			|||||||
                <p>{{ post.short_content }}</p>
 | 
					                <p>{{ post.short_content }}</p>
 | 
				
			||||||
                <h6><a href="/posts/{{ post.id }}">View post</a>
 | 
					                <h6><a href="/posts/{{ post.id }}">View post</a>
 | 
				
			||||||
                    {% if post.replies|length > 0 %}
 | 
					                    {% if post.replies|length > 0 %}
 | 
				
			||||||
                     | ({{ post.replies|length }} replies)
 | 
					                     ({{ post.replies|length }} replies)
 | 
				
			||||||
                    {% endif %}
 | 
					                    {% endif %}
 | 
				
			||||||
                    {% if session.name == "SYSTEM" %}
 | 
					                    {% if session.name == "SYSTEM" %}
 | 
				
			||||||
                     | <a href="/delete/post/{{ post.id }}">Delete</a>
 | 
					                     | <a href="/delete/post/{{ post.id }}">Delete</a>
 | 
				
			||||||
 | 
					                    {% elif session.name == post.user.name %}
 | 
				
			||||||
 | 
					                     | <a href="/delete/post/{{ post.id }}">Delete</a>
 | 
				
			||||||
                    {% endif %}
 | 
					                    {% endif %}
 | 
				
			||||||
                </h6>
 | 
					                </h6>
 | 
				
			||||||
            </li>
 | 
					            </li>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,7 +14,16 @@
 | 
				
			|||||||
                <h6><b>ref post:</b> <a href="/posts/{{ post.reference.id }}">{{ post.reference.content }}</a></h6>
 | 
					                <h6><b>ref post:</b> <a href="/posts/{{ post.reference.id }}">{{ post.reference.content }}</a></h6>
 | 
				
			||||||
                {% endif %}
 | 
					                {% endif %}
 | 
				
			||||||
                <p>{{ post.content }}</p>
 | 
					                <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>
 | 
					            </li>
 | 
				
			||||||
        {% endfor %}
 | 
					        {% endfor %}
 | 
				
			||||||
        {% if user.posts|length == 0 %}
 | 
					        {% 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)
 | 
					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
 | 
					# Initialize Flask app
 | 
				
			||||||
logger.info("Initializing Flask app...")
 | 
					logger.info("Initializing Flask app...")
 | 
				
			||||||
app = Flask(__name__, template_folder=os.getenv('TEMPLATE_FOLDER', 'html'), static_folder=os.getenv('STATIC_FOLDER', 'static'))
 | 
					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("Running first time setup...")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    logger.info("Creating SYSTEM user...")
 | 
					    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]
 | 
					    SYSTEMUID = db.get_user('SYSTEM')[0]
 | 
				
			||||||
    logger.info("SYSTEM user created with UID: %s", SYSTEMUID)
 | 
					    logger.info("SYSTEM user created with UID: %s", SYSTEMUID)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -61,30 +88,6 @@ else:
 | 
				
			|||||||
logger.info("Database initialized.")
 | 
					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
 | 
					# Define routes
 | 
				
			||||||
@app.route('/')
 | 
					@app.route('/')
 | 
				
			||||||
def index():
 | 
					def index():
 | 
				
			||||||
@@ -337,6 +340,35 @@ def register():
 | 
				
			|||||||
    return render_template('register.html')
 | 
					    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
 | 
					# Main function
 | 
				
			||||||
if __name__ == '__main__':
 | 
					if __name__ == '__main__':
 | 
				
			||||||
    logger.info("Starting Flask app...")
 | 
					    logger.info("Starting Flask app...")
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user