diff --git a/tildes/tildes/views/api/beta/topic.py b/tildes/tildes/views/api/beta/topic.py index 75ae289..5016686 100644 --- a/tildes/tildes/views/api/beta/topic.py +++ b/tildes/tildes/views/api/beta/topic.py @@ -19,35 +19,74 @@ from tildes.views.api.beta.api_utils import ( from tildes.views.api.beta.comment import comment_subtree_to_api_dict -def topic_to_api_dict(topic: Topic) -> dict: +def topic_to_api_dict(request: Request, topic: Topic) -> dict: """Convert a Topic object to a dictionary for JSON serialization. The schema is defined in our OpenAPI YAML file. """ + + # Some fields do not require permissions + topic_id = topic.topic_id36 + title = topic.title + comments_url = topic.permalink + group = str(topic.group.path) + created_at = topic.created_time.isoformat() + edited_at = topic.last_edited_time.isoformat() if topic.last_edited_time else None + vote_count = topic.num_votes + comment_count = topic.num_comments + new_comment_count = topic.comments_since_last_visit + official = topic.is_official + tags = topic.tags + last_visited_at = ( + topic.last_visit_time.isoformat() if topic.last_visit_time else None + ) + + # Check permissions for viewing topic details (and set safe defaults) + text_html = None + url = None + content_metadata = None + posted_by_user = "unknown user" + voted = False + bookmarked = False + ignored = False + + if request.has_permission("view_content", topic): + text_html = topic.rendered_html + url = topic.link + content_metadata = topic.content_metadata_for_display + + if request.has_permission("view_author", topic): + posted_by_user = topic.user.username + + if request.has_permission("vote", topic): + voted = topic.user_voted + + if request.has_permission("bookmark", topic): + bookmarked = topic.user_bookmarked + + if request.has_permission("ignore", topic): + ignored = topic.user_ignored + return { - "id": topic.topic_id36, - "title": topic.title, - "text_html": topic.rendered_html, - "url": topic.link, - "comments_url": topic.permalink, - "group": str(topic.group.path), - "content_metadata": topic.content_metadata_for_display, - "created_at": topic.created_time.isoformat(), - "edited_at": ( - topic.last_edited_time.isoformat() if topic.last_edited_time else None - ), - "posted_by_user": topic.user.username, - "vote_count": topic.num_votes, - "comment_count": topic.num_comments, - "new_comment_count": topic.comments_since_last_visit, - "voted": topic.user_voted, - "bookmarked": topic.user_bookmarked, - "ignored": topic.user_ignored, - "official": topic.is_official, - "tags": topic.tags, - "last_visited_at": ( - topic.last_visit_time.isoformat() if topic.last_visit_time else None - ), + "id": topic_id, + "title": title, + "text_html": text_html, + "url": url, + "comments_url": comments_url, + "group": group, + "content_metadata": content_metadata, + "created_at": created_at, + "edited_at": edited_at, + "posted_by_user": posted_by_user, + "vote_count": vote_count, + "comment_count": comment_count, + "new_comment_count": new_comment_count, + "voted": voted, + "bookmarked": bookmarked, + "ignored": ignored, + "official": official, + "tags": tags, + "last_visited_at": last_visited_at, } @@ -100,7 +139,7 @@ def get_topics(request: Request) -> dict | Response: # noqa: MC0001 # Build the JSON topic data for topic in topics: - processed_topic = topic_to_api_dict(topic) + processed_topic = topic_to_api_dict(request, topic) processed_topics.append(processed_topic) # Construct the paging next and previous link if there are more topics @@ -171,7 +210,7 @@ def get_topic(request: Request) -> dict | Response: # Construct the final response JSON object response = { - "topic": topic_to_api_dict(topic), + "topic": topic_to_api_dict(request, topic), "comments": commentsjson, } return response diff --git a/tildes/tildes/views/api/beta/user.py b/tildes/tildes/views/api/beta/user.py index 36ce682..3b65bf7 100644 --- a/tildes/tildes/views/api/beta/user.py +++ b/tildes/tildes/views/api/beta/user.py @@ -101,7 +101,7 @@ def get_user(request: Request) -> dict | Response: # noqa: MC0001 processed_results = [] for item in combined_results.results: if isinstance(item, Topic): - processed_results.append(topic_to_api_dict(item)) + processed_results.append(topic_to_api_dict(request, item)) elif isinstance(item, Comment): processed_results.append(comment_to_api_dict(request, item)) @@ -216,7 +216,7 @@ def get_user_topics(request: Request) -> dict | Response: # Build the JSON history data processed_topics = [] for topic in query_result.results: - processed_topics.append(topic_to_api_dict(topic)) + processed_topics.append(topic_to_api_dict(request, topic)) # Construct the paging next and previous link if there are more topics (next_link, prev_link) = get_next_and_prev_link(request, query_result)