Skip to content

Commit

Permalink
feat(threads-by-username): implement route for retreiving threads by …
Browse files Browse the repository at this point in the history
…username
  • Loading branch information
akinsey committed Oct 18, 2024
1 parent b34afcc commit 02bef0e
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 21 deletions.
34 changes: 18 additions & 16 deletions lib/epochtalk_server_web/controllers/post.ex
Original file line number Diff line number Diff line change
Expand Up @@ -427,50 +427,52 @@ defmodule EpochtalkServerWeb.Controllers.Post do
end
end

## === Private Authorization Helper Functions ===
## === Public Authorization Helper Functions ===

defp can_authed_user_view_deleted_posts(nil, _thread_id), do: false
def can_authed_user_view_deleted_posts_by_username(nil), do: false

defp can_authed_user_view_deleted_posts(user, thread_id) do
view_all = ACL.has_permission(user, "posts.byThread.bypass.viewDeletedPosts.admin")
view_some = ACL.has_permission(user, "posts.byThread.bypass.viewDeletedPosts.mod")
view_self_mod = ACL.has_permission(user, "posts.byThread.bypass.viewDeletedPosts.selfMod")
view_priority = ACL.has_permission(user, "posts.byThread.bypass.viewDeletedPosts.priority")
def can_authed_user_view_deleted_posts_by_username(user) do
view_all = ACL.has_permission(user, "posts.pageByUser.bypass.viewDeletedPosts.admin")
view_some = ACL.has_permission(user, "posts.pageByUser.bypass.viewDeletedPosts.mod")

user_id = Map.get(user, :id)
moderated_boards = BoardModerator.get_user_moderated_boards(user_id)

cond do
view_all or view_priority ->
view_all ->
true

view_some and moderated_boards != [] ->
moderated_boards

view_self_mod and moderated_boards == [] ->
Thread.self_moderated_by_user?(thread_id, user_id)

true ->
false
end
end

defp can_authed_user_view_deleted_posts_by_username(nil), do: false
## === Private Authorization Helper Functions ===

defp can_authed_user_view_deleted_posts_by_username(user) do
view_all = ACL.has_permission(user, "posts.byUsername.bypass.viewDeletedPosts.admin")
view_some = ACL.has_permission(user, "posts.byUsername.bypass.viewDeletedPosts.mod")
defp can_authed_user_view_deleted_posts(nil, _thread_id), do: false

defp can_authed_user_view_deleted_posts(user, thread_id) do
view_all = ACL.has_permission(user, "posts.byThread.bypass.viewDeletedPosts.admin")
view_some = ACL.has_permission(user, "posts.byThread.bypass.viewDeletedPosts.mod")
view_self_mod = ACL.has_permission(user, "posts.byThread.bypass.viewDeletedPosts.selfMod")
view_priority = ACL.has_permission(user, "posts.byThread.bypass.viewDeletedPosts.priority")

user_id = Map.get(user, :id)
moderated_boards = BoardModerator.get_user_moderated_boards(user_id)

cond do
view_all ->
view_all or view_priority ->
true

view_some and moderated_boards != [] ->
moderated_boards

view_self_mod and moderated_boards == [] ->
Thread.self_moderated_by_user?(thread_id, user_id)

true ->
false
end
Expand Down
53 changes: 53 additions & 0 deletions lib/epochtalk_server_web/controllers/thread.ex
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,59 @@ defmodule EpochtalkServerWeb.Controllers.Thread do
end
end

@doc """
Used to retrieve `Threads` for a `User` by username
"""
def by_username(conn, attrs) do
# Parameter Validation
with username <- attrs["username"],
page <- Validate.cast(attrs, "page", :integer, default: 1, min: 1),
limit <- Validate.cast(attrs, "limit", :integer, default: 25, min: 1, max: 100),
desc <- Validate.cast(attrs, "desc", :boolean, default: true),
user <- Guardian.Plug.current_resource(conn),
priority <- ACL.get_user_priority(conn),
[lookup_user] <- User.ids_from_usernames([username]),

# Authorizations Checks (Same permission as post page by user)
:ok <- ACL.allow!(conn, "posts.pageByUser"),
{:user_not_deleted, user_not_deleted} <-
{:user_not_deleted, User.is_active?(lookup_user.id)},
{:has_deleted_override, has_deleted_override} <-
{:has_deleted_override,
ACL.has_permission(conn, "posts.pageFirstPostByUser.bypass.viewDeletedUsers")},
{:view_deleted_users, true} <-
{:view_deleted_users, user_not_deleted || has_deleted_override},
view_deleted_threads <-
EpochtalkServerWeb.Controllers.Post.can_authed_user_view_deleted_posts_by_username(
user
),
threads <-
Thread.page_by_username(username, priority, page,
per_page: limit + 1,
desc: desc
),
{:has_threads, true} <- {:has_threads, threads != []} do
render(conn, :by_username, %{
threads: threads,
user: user,
priority: priority,
view_deleted_threads: view_deleted_threads,
limit: limit,
desc: desc,
page: page
})
else
{:has_threads, false} ->
ErrorHelpers.render_json_error(conn, 404, "Error, requested threads not found")

{:view_deleted_users, false} ->
ErrorHelpers.render_json_error(conn, 400, "Account not found")

_ ->
ErrorHelpers.render_json_error(conn, 400, "Error, cannot get threads by username")
end
end

@doc """
Used to watch `Thread`
"""
Expand Down
14 changes: 9 additions & 5 deletions lib/epochtalk_server_web/json/post_json.ex
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,9 @@ defmodule EpochtalkServerWeb.Controllers.PostJSON do
}
end

## === Private Helper Functions ===
## === Public Helper Functions ===

defp handle_deleted_posts(posts, thread, user, authed_user_priority, view_deleted_posts) do
def handle_deleted_posts(posts, thread, user, authed_user_priority, view_deleted_posts) do
authed_user_id = if is_nil(user), do: nil, else: user.id

has_self_mod_bypass =
Expand Down Expand Up @@ -163,6 +163,8 @@ defmodule EpochtalkServerWeb.Controllers.PostJSON do
cleaned_posts
end

## === Private Helper Functions ===

defp handle_deleted_post(
post,
authed_user_id,
Expand All @@ -186,9 +188,11 @@ defmodule EpochtalkServerWeb.Controllers.PostJSON do

# check if user has priority to view hidden post,
# or if the user was the one who hid the post
authed_user_has_priority = if is_nil(post_hidden_by_priority),
do: false,
else: authed_user_priority <= post_hidden_by_priority
authed_user_has_priority =
if is_nil(post_hidden_by_priority),
do: false,
else: authed_user_priority <= post_hidden_by_priority

authed_user_hid_post = post_hidden_by_id == authed_user_id

post_is_viewable =
Expand Down
35 changes: 35 additions & 0 deletions lib/epochtalk_server_web/json/thread_json.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
defmodule EpochtalkServerWeb.Controllers.ThreadJSON do
alias EpochtalkServerWeb.Controllers.BoardJSON
alias EpochtalkServerWeb.Controllers.PostJSON

@moduledoc """
Renders and formats `Thread` data, in JSON format for frontend
Expand Down Expand Up @@ -127,6 +128,40 @@ defmodule EpochtalkServerWeb.Controllers.ThreadJSON do
if board_banned, do: Map.put(result, :board_banned, board_banned), else: result
end

@doc """
Renders paged `Threads` for a particular `User`.
"""
def by_username(%{
threads: threads,
user: user,
priority: priority,
view_deleted_threads: view_deleted_threads,
limit: limit,
desc: desc,
page: page
}) do
next = length(threads) > limit

threads =
if next,
do: threads |> Enum.reverse() |> tl() |> Enum.reverse(),
else: threads

threads =
threads
|> Enum.map(&(Map.put(&1, :body_html, &1.body) |> Map.delete(:body)))
|> PostJSON.handle_deleted_posts(nil, user, priority, view_deleted_threads)

%{
posts: threads,
desc: desc,
limit: limit,
page: page,
next: next,
prev: page > 1
}
end

@doc """
Renders sticky `Thread`.
Expand Down
1 change: 1 addition & 0 deletions lib/epochtalk_server_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ defmodule EpochtalkServerWeb.Router do
get "/users/:username", User, :find
get "/posts", Post, :by_thread
get "/posts/user/:username", Post, :by_username
get "/threads/user/:username", Thread, :by_username
get "/threads", Thread, :by_board
get "/threads/:slug/id", Thread, :slug_to_id
post "/threads/:id/viewed", Thread, :viewed
Expand Down

0 comments on commit 02bef0e

Please sign in to comment.