From a3e20b6d0c6b88768a59c3e7ac102c5c2321ccc7 Mon Sep 17 00:00:00 2001 From: Anthony Kinsey Date: Tue, 31 Oct 2023 08:59:26 -1000 Subject: [PATCH 01/20] feat(controllers/board): add authorizations for Boards by category --- lib/epochtalk_server_web/controllers/board.ex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/epochtalk_server_web/controllers/board.ex b/lib/epochtalk_server_web/controllers/board.ex index 53943fc6..c747ef17 100644 --- a/lib/epochtalk_server_web/controllers/board.ex +++ b/lib/epochtalk_server_web/controllers/board.ex @@ -16,7 +16,8 @@ defmodule EpochtalkServerWeb.Controllers.Board do Used to retrieve categorized boards """ def by_category(conn, attrs) do - with stripped <- Validate.cast(attrs, "stripped", :boolean, default: false), + with :ok <- ACL.allow!(conn, "boards.allCategories"), + stripped <- Validate.cast(attrs, "stripped", :boolean, default: false), user_priority <- ACL.get_user_priority(conn), board_mapping <- BoardMapping.all(stripped: stripped), board_moderators <- BoardModerator.all(), From 5c4b3f7c88b6e8e83df8e6d964acfed831c15480 Mon Sep 17 00:00:00 2001 From: Anthony Kinsey Date: Tue, 31 Oct 2023 09:18:12 -1000 Subject: [PATCH 02/20] feat(controllers/board): add authorizations acl check for Boards find --- lib/epochtalk_server_web/controllers/board.ex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/epochtalk_server_web/controllers/board.ex b/lib/epochtalk_server_web/controllers/board.ex index c747ef17..9323bd58 100644 --- a/lib/epochtalk_server_web/controllers/board.ex +++ b/lib/epochtalk_server_web/controllers/board.ex @@ -37,7 +37,8 @@ defmodule EpochtalkServerWeb.Controllers.Board do Used to find a specific board """ def find(conn, attrs) do - with id <- Validate.cast(attrs, "id", :integer, required: true), + with :ok <- ACL.allow!(conn, "boards.find"), + id <- Validate.cast(attrs, "id", :integer, required: true), user_priority <- ACL.get_user_priority(conn), board_mapping <- BoardMapping.all(), board_moderators <- BoardModerator.all(), From cdd1ccaaae22764ac1f7b7f565b18a3f3c664175 Mon Sep 17 00:00:00 2001 From: Anthony Kinsey Date: Tue, 31 Oct 2023 09:48:22 -1000 Subject: [PATCH 03/20] feat(controllers/board): add authorizations checking if authed user can read board for Boards find --- lib/epochtalk_server_web/controllers/board.ex | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/epochtalk_server_web/controllers/board.ex b/lib/epochtalk_server_web/controllers/board.ex index 9323bd58..d9beb44d 100644 --- a/lib/epochtalk_server_web/controllers/board.ex +++ b/lib/epochtalk_server_web/controllers/board.ex @@ -40,6 +40,8 @@ defmodule EpochtalkServerWeb.Controllers.Board do with :ok <- ACL.allow!(conn, "boards.find"), id <- Validate.cast(attrs, "id", :integer, required: true), user_priority <- ACL.get_user_priority(conn), + {:can_read, {:ok, true}} <- + {:can_read, Board.get_read_access_by_id(id, user_priority)}, board_mapping <- BoardMapping.all(), board_moderators <- BoardModerator.all(), {:board, [_board]} <- @@ -51,6 +53,14 @@ defmodule EpochtalkServerWeb.Controllers.Board do user_priority: user_priority }) else + # if user can't read board, return 404, user doesn't need to know hidden board exists + {:can_read, {:ok, false}} -> + ErrorHelpers.render_json_error( + conn, + 404, + "Board not found" + ) + {:board, []} -> ErrorHelpers.render_json_error(conn, 400, "Error, board does not exist") _ -> ErrorHelpers.render_json_error(conn, 400, "Error, cannot fetch boards") end From b3e5beec048ae2dc44139f4219d8e0504ab2d120 Mon Sep 17 00:00:00 2001 From: Anthony Kinsey Date: Tue, 31 Oct 2023 09:54:01 -1000 Subject: [PATCH 04/20] style(format): run mix format --- lib/epochtalk_server_web/controllers/board.ex | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/epochtalk_server_web/controllers/board.ex b/lib/epochtalk_server_web/controllers/board.ex index d9beb44d..7c7ebb5d 100644 --- a/lib/epochtalk_server_web/controllers/board.ex +++ b/lib/epochtalk_server_web/controllers/board.ex @@ -61,8 +61,11 @@ defmodule EpochtalkServerWeb.Controllers.Board do "Board not found" ) - {:board, []} -> ErrorHelpers.render_json_error(conn, 400, "Error, board does not exist") - _ -> ErrorHelpers.render_json_error(conn, 400, "Error, cannot fetch boards") + {:board, []} -> + ErrorHelpers.render_json_error(conn, 400, "Error, board does not exist") + + _ -> + ErrorHelpers.render_json_error(conn, 400, "Error, cannot fetch boards") end end From 29e316c52f138dbf2d15b690cda266afd3b07377 Mon Sep 17 00:00:00 2001 From: Anthony Kinsey Date: Tue, 31 Oct 2023 10:57:38 -1000 Subject: [PATCH 05/20] fix(controller/board): resolve issue with wrong error being thrown after adding acls --- lib/epochtalk_server_web/controllers/board.ex | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/epochtalk_server_web/controllers/board.ex b/lib/epochtalk_server_web/controllers/board.ex index 7c7ebb5d..2e421da2 100644 --- a/lib/epochtalk_server_web/controllers/board.ex +++ b/lib/epochtalk_server_web/controllers/board.ex @@ -61,6 +61,9 @@ defmodule EpochtalkServerWeb.Controllers.Board do "Board not found" ) + {:can_read, {:error, :board_does_not_exist}} -> + ErrorHelpers.render_json_error(conn, 400, "Error, board does not exist") + {:board, []} -> ErrorHelpers.render_json_error(conn, 400, "Error, board does not exist") From 54ee77475f437ae717c3dc64ca65edafc3dfe192 Mon Sep 17 00:00:00 2001 From: unenglishable Date: Thu, 2 Nov 2023 14:24:27 -0700 Subject: [PATCH 06/20] test(seed+conn_case): seed private user and prepare in conn_case can be used for checking acl's (private user can only access motd) --- test/seed/users.exs | 11 +++++++++++ test/support/conn_case.ex | 24 ++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/test/seed/users.exs b/test/seed/users.exs index 88aa2f65..45c96449 100644 --- a/test/seed/users.exs +++ b/test/seed/users.exs @@ -12,6 +12,10 @@ test_user_username = "user" test_user_email = "user@test.com" test_user_password = "password" +test_private_user_username = "private" +test_private_user_email = "private@test.com" +test_private_user_password = "password" + test_no_login_user_username = "no_login" test_no_login_user_email = "no_login@test.com" test_no_login_user_password = "password" @@ -36,6 +40,13 @@ build(:user, password: test_user_password ) +build(:user, + username: test_private_user_username, + email: test_private_user_email, + password: test_private_user_password +) +|> with_role_id(10) + build(:user, username: test_no_login_user_username, email: test_no_login_user_email, diff --git a/test/support/conn_case.ex b/test/support/conn_case.ex index 26cff653..8c1372e1 100644 --- a/test/support/conn_case.ex +++ b/test/support/conn_case.ex @@ -25,6 +25,16 @@ defmodule Test.Support.ConnCase do password: @test_no_login_password } + # private username/email/password from user seed in `mix test` (see mix.exs) + @test_private_username "private" + @test_private_email "private@test.com" + @test_private_password "password" + @test_private_user_attrs %{ + username: @test_private_username, + email: @test_private_email, + password: @test_private_password + } + # username/email/password from user seed in `mix test` (see mix.exs) @test_username "user" @test_email "user@test.com" @@ -86,6 +96,7 @@ defmodule Test.Support.ConnCase do end {:ok, no_login_user} = User.by_username(@test_no_login_username) + {:ok, private_user} = User.by_username(@test_private_username) {:ok, user} = User.by_username(@test_username) {:ok, admin_user} = User.by_username(@test_admin_username) {:ok, super_admin_user} = User.by_username(@test_super_admin_username) @@ -96,12 +107,14 @@ defmodule Test.Support.ConnCase do [ users: %{ no_login_user: no_login_user, + private_user: private_user, user: user, admin_user: admin_user, super_admin_user: super_admin_user }, user_attrs: %{ no_login_user: @test_no_login_user_attrs, + private_user: @test_private_user_attrs, user: @test_user_attrs, admin_user: @test_admin_user_attrs, super_admin_user: @test_super_admin_user_attrs @@ -122,6 +135,17 @@ defmodule Test.Support.ConnCase do k_list = [authed_user_attrs: @test_user_attrs] ++ k_list {:ok, k_list} + :private -> + remember_me = false + {:ok, private_user, token, authed_conn} = Session.create(private_user, remember_me, conn) + + {:ok, k_list} = context_updates + k_list = [conn: authed_conn] ++ k_list + k_list = [authed_user: private_user] ++ k_list + k_list = [token: token] ++ k_list + k_list = [authed_user_attrs: @test_private_user_attrs] ++ k_list + {:ok, k_list} + :admin -> remember_me = false {:ok, admin_user, token, authed_conn} = Session.create(admin_user, remember_me, conn) From f2364d59a251bf3e6282af001a9cef76010d7e59 Mon Sep 17 00:00:00 2001 From: unenglishable Date: Thu, 2 Nov 2023 14:27:47 -0700 Subject: [PATCH 07/20] test(controllers/board): check by_category errors on invalid permissions --- test/epochtalk_server_web/controllers/board_test.exs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/epochtalk_server_web/controllers/board_test.exs b/test/epochtalk_server_web/controllers/board_test.exs index 66a8878f..64d5430b 100644 --- a/test/epochtalk_server_web/controllers/board_test.exs +++ b/test/epochtalk_server_web/controllers/board_test.exs @@ -30,6 +30,14 @@ defmodule Test.EpochtalkServerWeb.Controllers.Board do end describe "by_category/2" do + @tag authenticated: :private + test "when authenticated with invalid permissions, raises InvalidPermission error", %{conn: conn} do + assert_raise InvalidPermission, + ~r/^Forbidden, invalid permissions to perform this action/, + fn -> + get(conn, Routes.board_path(conn, :by_category)) + end + end test "finds all active boards", %{ conn: conn, category: category, From 12f4d80fa8118c52a37fb2b12834a4407f93ce73 Mon Sep 17 00:00:00 2001 From: unenglishable Date: Thu, 2 Nov 2023 14:34:05 -0700 Subject: [PATCH 08/20] test(controllers/board): check invalid board read access for unauthenticated user --- test/epochtalk_server_web/controllers/board_test.exs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/epochtalk_server_web/controllers/board_test.exs b/test/epochtalk_server_web/controllers/board_test.exs index 64d5430b..965b42a0 100644 --- a/test/epochtalk_server_web/controllers/board_test.exs +++ b/test/epochtalk_server_web/controllers/board_test.exs @@ -138,6 +138,16 @@ defmodule Test.EpochtalkServerWeb.Controllers.Board do assert response["message"] == "Error, board does not exist" end + test "when unauthenticated, given an existing id above read access, errors", %{conn: conn, admin_board: admin_board} do + response = + conn + |> get(Routes.board_path(conn, :find, admin_board.id)) + |> json_response(404) + + assert response["error"] == "Not Found" + assert response["message"] == "Board not found" + end + test "given an existing id, finds a board", %{conn: conn, parent_board: board} do response = conn From 3ce8b88b0adad13b71295c2b190bc81d9a2b64b9 Mon Sep 17 00:00:00 2001 From: Anthony Kinsey Date: Thu, 2 Nov 2023 11:35:20 -1000 Subject: [PATCH 09/20] test(seed/users): add seed for every role type --- test/seed/users.exs | 78 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/test/seed/users.exs b/test/seed/users.exs index 85afe68a..413539ad 100644 --- a/test/seed/users.exs +++ b/test/seed/users.exs @@ -8,10 +8,38 @@ test_admin_user_username = "admin" test_admin_user_email = "admin@test.com" test_admin_user_password = "password" +test_global_mod_user_username = "globalmod" +test_global_mod_user_email = "globalmod@test.com" +test_global_mod_user_password = "password" + +test_mod_user_username = "mod" +test_mod_user_email = "mod@test.com" +test_mod_user_password = "password" + test_user_username = "user" test_user_email = "user@test.com" test_user_password = "password" +test_patroller_user_username = "patroller" +test_patroller_user_email = "patroller@test.com" +test_patroller_user_password = "password" + +test_newbie_user_username = "newbie" +test_newbie_user_email = "newbie@test.com" +test_newbie_user_password = "password" + +test_banned_user_username = "banned" +test_banned_user_email = "banned@test.com" +test_banned_user_password = "password" + +test_anonymous_user_username = "anonymous" +test_anonymous_user_email = "anonymous@test.com" +test_anonymous_user_password = "password" + +test_private_user_username = "private" +test_private_user_email = "private@test.com" +test_private_user_password = "password" + build(:user, username: test_super_admin_user_username, email: test_super_admin_user_email, @@ -26,10 +54,60 @@ build(:user, ) |> with_role_id(2) +build(:user, + username: test_global_mod_user_username, + email: test_global_mod_user_email, + password: test_global_mod_user_password +) +|> with_role_id(3) + +build(:user, + username: test_mod_user_username, + email: test_mod_user_email, + password: test_mod_user_password +) +|> with_role_id(4) + build(:user, username: test_user_username, email: test_user_email, password: test_user_password ) +build(:user, + username: test_patroller_user_username, + email: test_patroller_user_email, + password: test_patroller_user_password +) +|> with_role_id(6) + +build(:user, + username: test_newbie_user_username, + email: test_newbie_user_email, + password: test_newbie_user_password +) +|> with_role_id(7) + +# TODO(akinsey): actually ban the user, this user only has banned role +build(:user, + username: test_banned_user_username, + email: test_banned_user_email, + password: test_banned_user_password +) +|> with_role_id(8) + +build(:user, + username: test_anonymous_user_username, + email: test_anonymous_user_email, + password: test_anonymous_user_password +) +|> with_role_id(9) + +build(:user, + username: test_private_user_username, + email: test_private_user_email, + password: test_private_user_password +) +|> with_role_id(10) + IO.puts("Successfully seeded test users") From 8d43e8e59c06ff08a83ba86ef0bbb12dfccd2d13 Mon Sep 17 00:00:00 2001 From: Anthony Kinsey Date: Thu, 2 Nov 2023 12:17:52 -1000 Subject: [PATCH 10/20] test(conn_case): add all new roles from user seed to conn case --- test/support/conn_case.ex | 236 +++++++++++++++++++++++++++++++++----- 1 file changed, 207 insertions(+), 29 deletions(-) diff --git a/test/support/conn_case.ex b/test/support/conn_case.ex index 8bb47d61..db982e3b 100644 --- a/test/support/conn_case.ex +++ b/test/support/conn_case.ex @@ -15,17 +15,17 @@ defmodule Test.Support.ConnCase do this option is not recommended for other databases. """ - # username/email/password from user seed in `mix test` (see mix.exs) - @test_username "user" - @test_email "user@test.com" - @test_password "password" - @test_user_attrs %{ - username: @test_username, - email: @test_email, - password: @test_password + # super admin (1) username/email/password from user seed in `mix test` (see mix.exs) + @test_super_admin_username "superadmin" + @test_super_admin_email "superadmin@test.com" + @test_super_admin_password "password" + @test_super_admin_user_attrs %{ + username: @test_super_admin_username, + email: @test_super_admin_email, + password: @test_super_admin_password } - # admin username/email/password from user seed in `mix test` (see mix.exs) + # admin (2) username/email/password from user seed in `mix test` (see mix.exs) @test_admin_username "admin" @test_admin_email "admin@test.com" @test_admin_password "password" @@ -35,14 +35,84 @@ defmodule Test.Support.ConnCase do password: @test_admin_password } - # super admin username/email/password from user seed in `mix test` (see mix.exs) - @test_super_admin_username "superadmin" - @test_super_admin_email "superadmin@test.com" - @test_super_admin_password "password" - @test_super_admin_user_attrs %{ - username: @test_super_admin_username, - email: @test_super_admin_email, - password: @test_super_admin_password + # global mod (3) username/email/password from user seed in `mix test` (see mix.exs) + @test_global_mod_username "globalmod" + @test_global_mod_email "globalmod@test.com" + @test_global_mod_password "password" + @test_global_mod_user_attrs %{ + username: @test_global_mod_username, + email: @test_global_mod_email, + password: @test_global_mod_password + } + + # mod (4) username/email/password from user seed in `mix test` (see mix.exs) + @test_mod_username "mod" + @test_mod_email "mod@test.com" + @test_mod_password "password" + @test_mod_user_attrs %{ + username: @test_mod_username, + email: @test_mod_email, + password: @test_mod_password + } + + # user (5) username/email/password from user seed in `mix test` (see mix.exs) + @test_username "user" + @test_email "user@test.com" + @test_password "password" + @test_user_attrs %{ + username: @test_username, + email: @test_email, + password: @test_password + } + + # patroller (6) username/email/password from user seed in `mix test` (see mix.exs) + @test_patroller_username "patroller" + @test_patroller_email "patroller@test.com" + @test_patroller_password "password" + @test_patroller_user_attrs %{ + username: @test_patroller_username, + email: @test_patroller_email, + password: @test_patroller_password + } + + # newbie (7) username/email/password from user seed in `mix test` (see mix.exs) + @test_newbie_username "newbie" + @test_newbie_email "newbie@test.com" + @test_newbie_password "password" + @test_newbie_user_attrs %{ + username: @test_newbie_username, + email: @test_newbie_email, + password: @test_newbie_password + } + + # banned (8) username/email/password from user seed in `mix test` (see mix.exs) + @test_banned_username "banned" + @test_banned_email "banned@test.com" + @test_banned_password "password" + @test_banned_user_attrs %{ + username: @test_banned_username, + email: @test_banned_email, + password: @test_banned_password + } + + # anonymous (9) username/email/password from user seed in `mix test` (see mix.exs) + @test_anonymous_username "anonymous" + @test_anonymous_email "anonymous@test.com" + @test_anonymous_password "password" + @test_anonymous_user_attrs %{ + username: @test_anonymous_username, + email: @test_anonymous_email, + password: @test_anonymous_password + } + + # private (10) username/email/password from user seed in `mix test` (see mix.exs) + @test_private_username "private" + @test_private_email "private@test.com" + @test_private_password "password" + @test_private_user_attrs %{ + username: @test_private_username, + email: @test_private_email, + password: @test_private_password } use ExUnit.CaseTemplate @@ -75,29 +145,52 @@ defmodule Test.Support.ConnCase do Ecto.Adapters.SQL.Sandbox.mode(EpochtalkServer.Repo, {:shared, self()}) end - {:ok, user} = User.by_username(@test_username) - {:ok, admin_user} = User.by_username(@test_admin_username) {:ok, super_admin_user} = User.by_username(@test_super_admin_username) + {:ok, admin_user} = User.by_username(@test_admin_username) + {:ok, global_mod_user} = User.by_username(@test_global_mod_username) + {:ok, mod_user} = User.by_username(@test_mod_username) + {:ok, user} = User.by_username(@test_username) + {:ok, patroller_user} = User.by_username(@test_patroller_username) + {:ok, newbie_user} = User.by_username(@test_newbie_username) + {:ok, banned_user} = User.by_username(@test_banned_username) + {:ok, anonymous_user} = User.by_username(@test_anonymous_username) + {:ok, private_user} = User.by_username(@test_private_username) + conn = Phoenix.ConnTest.build_conn() context_updates = {:ok, [ users: %{ - user: user, + super_admin_user: super_admin_user, admin_user: admin_user, - super_admin_user: super_admin_user + global_mod_user: global_mod_user, + mod_user: mod_user, + user: user, + patroller_user: patroller_user, + newbie_user: newbie_user, + banned_user: banned_user, + anonymous_user: anonymous_user, + private_user: private_user }, user_attrs: %{ - user: @test_user_attrs, + super_admin_user: @test_super_admin_user_attrs, admin_user: @test_admin_user_attrs, - super_admin_user: @test_super_admin_user_attrs + global_mod_user: @test_global_mod_user_attrs, + mod_user: @test_mod_user_attrs, + user: @test_user_attrs, + patroller_user: @test_patroller_user_attrs, + newbie_user: @test_newbie_user_attrs, + banned_user: @test_banned_user_attrs, + anonymous_user: @test_anonymous_user_attrs, + private_user: @test_private_user_attrs } ]} # log user in if necessary context_updates = case context[:authenticated] do + # user default case true -> remember_me = false {:ok, user, token, authed_conn} = Session.create(user, remember_me, conn) @@ -109,6 +202,19 @@ defmodule Test.Support.ConnCase do k_list = [authed_user_attrs: @test_user_attrs] ++ k_list {:ok, k_list} + :super_admin -> + remember_me = false + + {:ok, super_admin_user, token, authed_conn} = + Session.create(super_admin_user, remember_me, conn) + + {:ok, k_list} = context_updates + k_list = [conn: authed_conn] ++ k_list + k_list = [authed_user: super_admin_user] ++ k_list + k_list = [token: token] ++ k_list + k_list = [authed_user_attrs: @test_super_admin_user_attrs] ++ k_list + {:ok, k_list} + :admin -> remember_me = false {:ok, admin_user, token, authed_conn} = Session.create(admin_user, remember_me, conn) @@ -120,17 +226,89 @@ defmodule Test.Support.ConnCase do k_list = [authed_user_attrs: @test_admin_user_attrs] ++ k_list {:ok, k_list} - :super_admin -> + :global_mod -> remember_me = false - {:ok, super_admin_user, token, authed_conn} = - Session.create(super_admin_user, remember_me, conn) + {:ok, global_mod_user, token, authed_conn} = + Session.create(global_mod_user, remember_me, conn) {:ok, k_list} = context_updates k_list = [conn: authed_conn] ++ k_list - k_list = [authed_user: super_admin_user] ++ k_list + k_list = [authed_user: global_mod_user] ++ k_list k_list = [token: token] ++ k_list - k_list = [authed_user_attrs: @test_super_admin_user_attrs] ++ k_list + k_list = [authed_user_attrs: @test_global_mod_user_attrs] ++ k_list + {:ok, k_list} + + :mod -> + remember_me = false + {:ok, mod_user, token, authed_conn} = Session.create(mod_user, remember_me, conn) + + {:ok, k_list} = context_updates + k_list = [conn: authed_conn] ++ k_list + k_list = [authed_user: mod_user] ++ k_list + k_list = [token: token] ++ k_list + k_list = [authed_user_attrs: @test_mod_user_attrs] ++ k_list + {:ok, k_list} + + :patroller -> + remember_me = false + + {:ok, patroller_user, token, authed_conn} = + Session.create(patroller_user, remember_me, conn) + + {:ok, k_list} = context_updates + k_list = [conn: authed_conn] ++ k_list + k_list = [authed_user: patroller_user] ++ k_list + k_list = [token: token] ++ k_list + k_list = [authed_user_attrs: @test_patroller_user_attrs] ++ k_list + {:ok, k_list} + + :newbie -> + remember_me = false + {:ok, newbie_user, token, authed_conn} = Session.create(newbie_user, remember_me, conn) + + {:ok, k_list} = context_updates + k_list = [conn: authed_conn] ++ k_list + k_list = [authed_user: newbie_user] ++ k_list + k_list = [token: token] ++ k_list + k_list = [authed_user_attrs: @test_newbie_user_attrs] ++ k_list + {:ok, k_list} + + :banned -> + remember_me = false + {:ok, banned_user, token, authed_conn} = Session.create(banned_user, remember_me, conn) + + {:ok, k_list} = context_updates + k_list = [conn: authed_conn] ++ k_list + k_list = [authed_user: banned_user] ++ k_list + k_list = [token: token] ++ k_list + k_list = [authed_user_attrs: @test_banned_user_attrs] ++ k_list + {:ok, k_list} + + :anonymous -> + remember_me = false + + {:ok, anonymous_user, token, authed_conn} = + Session.create(anonymous_user, remember_me, conn) + + {:ok, k_list} = context_updates + k_list = [conn: authed_conn] ++ k_list + k_list = [authed_user: anonymous_user] ++ k_list + k_list = [token: token] ++ k_list + k_list = [authed_user_attrs: @test_anonymous_user_attrs] ++ k_list + {:ok, k_list} + + :private -> + remember_me = false + + {:ok, private_user, token, authed_conn} = + Session.create(private_user, remember_me, conn) + + {:ok, k_list} = context_updates + k_list = [conn: authed_conn] ++ k_list + k_list = [authed_user: private_user] ++ k_list + k_list = [token: token] ++ k_list + k_list = [authed_user_attrs: @test_private_user_attrs] ++ k_list {:ok, k_list} # :authenticated not set, return default conn @@ -143,7 +321,7 @@ defmodule Test.Support.ConnCase do # ban user if necessary context_updates = if context[:banned] do - {:ok, banned_user_changeset} = Ban.ban(user) + {:ok, banned_user_changeset} = Ban.ban(banned_user) {:ok, k_list} = context_updates {:ok, [banned_user_changeset: banned_user_changeset] ++ k_list} else From 88ffd0c552980bcbb04c92db60c254b6ff224be6 Mon Sep 17 00:00:00 2001 From: Anthony Kinsey Date: Thu, 2 Nov 2023 12:20:08 -1000 Subject: [PATCH 11/20] test(session_test): updating tests with banned tag to use banned user --- test/epochtalk_server/session_test.exs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/epochtalk_server/session_test.exs b/test/epochtalk_server/session_test.exs index 1544fb7b..1632e0cb 100644 --- a/test/epochtalk_server/session_test.exs +++ b/test/epochtalk_server/session_test.exs @@ -245,8 +245,8 @@ defmodule Test.EpochtalkServer.Session do @tag :banned test "without remember me, handles baninfo ttl and ban_expiration (< 1 day ttl)", %{ conn: conn, - user_attrs: %{user: user_attrs}, - users: %{user: user} + user_attrs: %{banned_user: user_attrs}, + users: %{banned_user: user} } do pre_ban_baninfo_ttl = Redix.command!(:redix, ["TTL", "user:#{user.id}:baninfo"]) @@ -276,8 +276,8 @@ defmodule Test.EpochtalkServer.Session do @tag :banned test "with remember me, handles baninfo ttl and ban_expiration (< 4 weeks ttl)", %{ conn: conn, - user_attrs: %{user: user_attrs}, - users: %{user: user} + user_attrs: %{banned_user: user_attrs}, + users: %{banned_user: user} } do pre_ban_baninfo_ttl = Redix.command!(:redix, ["TTL", "user:#{user.id}:baninfo"]) From db74461f899416ef66f3f4f9e1f9d6885fb438c3 Mon Sep 17 00:00:00 2001 From: Anthony Kinsey Date: Thu, 2 Nov 2023 12:20:52 -1000 Subject: [PATCH 12/20] test(models/mention): update mention test to user private role instead of banned to test invalid permissions --- test/epochtalk_server/models/mention_test.exs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/test/epochtalk_server/models/mention_test.exs b/test/epochtalk_server/models/mention_test.exs index 9a69f43a..fbea5f57 100644 --- a/test/epochtalk_server/models/mention_test.exs +++ b/test/epochtalk_server/models/mention_test.exs @@ -72,10 +72,7 @@ defmodule Test.EpochtalkServer.Models.Mention do assert result["mentioned_ids"] == [] end - @tag :banned - test "given a user without acl permission, errors", %{thread: thread} do - {:ok, user} = EpochtalkServer.Models.User.by_username("user") - + test "given a user without acl permission, errors", %{thread: thread, users: %{private_user: user}} do attrs = %{ "thread" => thread.id, "title" => "title", From 59d9649d355a9d9906d7b4bfb20cb24d2053eea3 Mon Sep 17 00:00:00 2001 From: Anthony Kinsey Date: Thu, 2 Nov 2023 12:21:21 -1000 Subject: [PATCH 13/20] style(format): run mix format --- test/epochtalk_server/models/mention_test.exs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/epochtalk_server/models/mention_test.exs b/test/epochtalk_server/models/mention_test.exs index fbea5f57..b4b4953c 100644 --- a/test/epochtalk_server/models/mention_test.exs +++ b/test/epochtalk_server/models/mention_test.exs @@ -72,7 +72,10 @@ defmodule Test.EpochtalkServer.Models.Mention do assert result["mentioned_ids"] == [] end - test "given a user without acl permission, errors", %{thread: thread, users: %{private_user: user}} do + test "given a user without acl permission, errors", %{ + thread: thread, + users: %{private_user: user} + } do attrs = %{ "thread" => thread.id, "title" => "title", From 241e51046fe55d7bad5a37ba2eb9b66350b8b201 Mon Sep 17 00:00:00 2001 From: unenglishable Date: Thu, 2 Nov 2023 15:23:03 -0700 Subject: [PATCH 14/20] test(controllers/board): update unauthenticated test description --- test/epochtalk_server_web/controllers/board_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/epochtalk_server_web/controllers/board_test.exs b/test/epochtalk_server_web/controllers/board_test.exs index 965b42a0..db374aa7 100644 --- a/test/epochtalk_server_web/controllers/board_test.exs +++ b/test/epochtalk_server_web/controllers/board_test.exs @@ -148,7 +148,7 @@ defmodule Test.EpochtalkServerWeb.Controllers.Board do assert response["message"] == "Board not found" end - test "given an existing id, finds a board", %{conn: conn, parent_board: board} do + test "when unauthenticated, given an existing id within read access, finds a board", %{conn: conn, parent_board: board} do response = conn |> get(Routes.board_path(conn, :find, board.id)) From 46e87d05d61b1d0daf88f14de282c587bf88131e Mon Sep 17 00:00:00 2001 From: unenglishable Date: Thu, 2 Nov 2023 15:49:07 -0700 Subject: [PATCH 15/20] test(controllers/board): check board find when authenticated --- .../controllers/board_test.exs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/test/epochtalk_server_web/controllers/board_test.exs b/test/epochtalk_server_web/controllers/board_test.exs index db374aa7..4fa00b2d 100644 --- a/test/epochtalk_server_web/controllers/board_test.exs +++ b/test/epochtalk_server_web/controllers/board_test.exs @@ -164,6 +164,27 @@ defmodule Test.EpochtalkServerWeb.Controllers.Board do assert response["disable_post_edit"] == board.meta["disable_post_edit"] assert response["disable_signature"] == board.meta["disable_signature"] end + + @tag :authenticated + test "when authenticated, given an existing id above read access, errors", %{conn: conn, admin_board: admin_board} do + response = + conn + |> get(Routes.board_path(conn, :find, admin_board.id)) + |> json_response(404) + + assert response["error"] == "Not Found" + assert response["message"] == "Board not found" + end + + @tag :authenticated + test "when authenticated, given an existing id at read access, finds board", %{conn: conn, parent_board: board} do + response = + conn + |> get(Routes.board_path(conn, :find, board.id)) + |> json_response(200) + + assert response["name"] == board.name + end end describe "slug_to_id/2" do From 95ed14eef5bef5348210507fe3748d99762bdd30 Mon Sep 17 00:00:00 2001 From: unenglishable Date: Thu, 2 Nov 2023 15:49:44 -0700 Subject: [PATCH 16/20] test(controllers/board): check board find when authenticated as admin --- .../controllers/board_test.exs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/test/epochtalk_server_web/controllers/board_test.exs b/test/epochtalk_server_web/controllers/board_test.exs index 4fa00b2d..df83902c 100644 --- a/test/epochtalk_server_web/controllers/board_test.exs +++ b/test/epochtalk_server_web/controllers/board_test.exs @@ -185,6 +185,27 @@ defmodule Test.EpochtalkServerWeb.Controllers.Board do assert response["name"] == board.name end + + @tag authenticated: :admin + test "when authenticated as admin, given an existing id at read access, finds board", %{conn: conn, admin_board: admin_board} do + response = + conn + |> get(Routes.board_path(conn, :find, admin_board.id)) + |> json_response(200) + + assert response["name"] == admin_board.name + end + + @tag authenticated: :admin + test "when authenticated as admin, given an existing id above read access, errors", %{conn: conn, super_admin_board: super_admin_board} do + response = + conn + |> get(Routes.board_path(conn, :find, super_admin_board.id)) + |> json_response(404) + + assert response["error"] == "Not Found" + assert response["message"] == "Board not found" + end end describe "slug_to_id/2" do From 55a1e6c5c488ba5a5ebf8042d96516e1d34d44e7 Mon Sep 17 00:00:00 2001 From: unenglishable Date: Thu, 2 Nov 2023 15:52:01 -0700 Subject: [PATCH 17/20] test(controllers/board): test super admin board find --- test/epochtalk_server_web/controllers/board_test.exs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/epochtalk_server_web/controllers/board_test.exs b/test/epochtalk_server_web/controllers/board_test.exs index df83902c..122f3273 100644 --- a/test/epochtalk_server_web/controllers/board_test.exs +++ b/test/epochtalk_server_web/controllers/board_test.exs @@ -206,6 +206,16 @@ defmodule Test.EpochtalkServerWeb.Controllers.Board do assert response["error"] == "Not Found" assert response["message"] == "Board not found" end + + @tag authenticated: :super_admin + test "when authenticated as super admin, given an existing id at read access, finds board", %{conn: conn, super_admin_board: super_admin_board} do + response = + conn + |> get(Routes.board_path(conn, :find, super_admin_board.id)) + |> json_response(200) + + assert response["name"] == super_admin_board.name + end end describe "slug_to_id/2" do From 57bc64d085bd80faf291f8ebb8076ba18468e682 Mon Sep 17 00:00:00 2001 From: unenglishable Date: Mon, 6 Nov 2023 12:27:11 -0800 Subject: [PATCH 18/20] test(session): use new banned role in test --- test/epochtalk_server/session_test.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/epochtalk_server/session_test.exs b/test/epochtalk_server/session_test.exs index 2ab6b650..48130c9a 100644 --- a/test/epochtalk_server/session_test.exs +++ b/test/epochtalk_server/session_test.exs @@ -447,7 +447,7 @@ defmodule Test.EpochtalkServer.Session do assert banned_resource_user.ban_expiration == @max_date end - @tag [authenticated: true, banned: true] + @tag [authenticated: :banned, banned: true] test "given a banned user's id, when user is unbanned, deletes banned role", %{ conn: conn, authed_user: authed_user From 5855fd9f6f93dc2722a43e05540e1067e8a49b23 Mon Sep 17 00:00:00 2001 From: unenglishable Date: Mon, 6 Nov 2023 12:40:56 -0800 Subject: [PATCH 19/20] test(controllers/board): mix format --- .../controllers/board_test.exs | 40 +++++++++++++++---- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/test/epochtalk_server_web/controllers/board_test.exs b/test/epochtalk_server_web/controllers/board_test.exs index 122f3273..7e403c06 100644 --- a/test/epochtalk_server_web/controllers/board_test.exs +++ b/test/epochtalk_server_web/controllers/board_test.exs @@ -31,13 +31,16 @@ defmodule Test.EpochtalkServerWeb.Controllers.Board do describe "by_category/2" do @tag authenticated: :private - test "when authenticated with invalid permissions, raises InvalidPermission error", %{conn: conn} do + test "when authenticated with invalid permissions, raises InvalidPermission error", %{ + conn: conn + } do assert_raise InvalidPermission, ~r/^Forbidden, invalid permissions to perform this action/, fn -> get(conn, Routes.board_path(conn, :by_category)) end end + test "finds all active boards", %{ conn: conn, category: category, @@ -138,7 +141,10 @@ defmodule Test.EpochtalkServerWeb.Controllers.Board do assert response["message"] == "Error, board does not exist" end - test "when unauthenticated, given an existing id above read access, errors", %{conn: conn, admin_board: admin_board} do + test "when unauthenticated, given an existing id above read access, errors", %{ + conn: conn, + admin_board: admin_board + } do response = conn |> get(Routes.board_path(conn, :find, admin_board.id)) @@ -148,7 +154,10 @@ defmodule Test.EpochtalkServerWeb.Controllers.Board do assert response["message"] == "Board not found" end - test "when unauthenticated, given an existing id within read access, finds a board", %{conn: conn, parent_board: board} do + test "when unauthenticated, given an existing id within read access, finds a board", %{ + conn: conn, + parent_board: board + } do response = conn |> get(Routes.board_path(conn, :find, board.id)) @@ -166,7 +175,10 @@ defmodule Test.EpochtalkServerWeb.Controllers.Board do end @tag :authenticated - test "when authenticated, given an existing id above read access, errors", %{conn: conn, admin_board: admin_board} do + test "when authenticated, given an existing id above read access, errors", %{ + conn: conn, + admin_board: admin_board + } do response = conn |> get(Routes.board_path(conn, :find, admin_board.id)) @@ -177,7 +189,10 @@ defmodule Test.EpochtalkServerWeb.Controllers.Board do end @tag :authenticated - test "when authenticated, given an existing id at read access, finds board", %{conn: conn, parent_board: board} do + test "when authenticated, given an existing id at read access, finds board", %{ + conn: conn, + parent_board: board + } do response = conn |> get(Routes.board_path(conn, :find, board.id)) @@ -187,7 +202,10 @@ defmodule Test.EpochtalkServerWeb.Controllers.Board do end @tag authenticated: :admin - test "when authenticated as admin, given an existing id at read access, finds board", %{conn: conn, admin_board: admin_board} do + test "when authenticated as admin, given an existing id at read access, finds board", %{ + conn: conn, + admin_board: admin_board + } do response = conn |> get(Routes.board_path(conn, :find, admin_board.id)) @@ -197,7 +215,10 @@ defmodule Test.EpochtalkServerWeb.Controllers.Board do end @tag authenticated: :admin - test "when authenticated as admin, given an existing id above read access, errors", %{conn: conn, super_admin_board: super_admin_board} do + test "when authenticated as admin, given an existing id above read access, errors", %{ + conn: conn, + super_admin_board: super_admin_board + } do response = conn |> get(Routes.board_path(conn, :find, super_admin_board.id)) @@ -208,7 +229,10 @@ defmodule Test.EpochtalkServerWeb.Controllers.Board do end @tag authenticated: :super_admin - test "when authenticated as super admin, given an existing id at read access, finds board", %{conn: conn, super_admin_board: super_admin_board} do + test "when authenticated as super admin, given an existing id at read access, finds board", %{ + conn: conn, + super_admin_board: super_admin_board + } do response = conn |> get(Routes.board_path(conn, :find, super_admin_board.id)) From fe38cd625221082623b4156b46027a692b5ed01b Mon Sep 17 00:00:00 2001 From: unenglishable Date: Mon, 6 Nov 2023 15:17:40 -0800 Subject: [PATCH 20/20] test(support/conn_case): fix merge --- test/support/conn_case.ex | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/support/conn_case.ex b/test/support/conn_case.ex index 90dbdedf..7afb0368 100644 --- a/test/support/conn_case.ex +++ b/test/support/conn_case.ex @@ -155,8 +155,6 @@ defmodule Test.Support.ConnCase do Ecto.Adapters.SQL.Sandbox.mode(EpochtalkServer.Repo, {:shared, self()}) end - {:ok, user} = User.by_username(@test_username) - {:ok, admin_user} = User.by_username(@test_admin_username) {:ok, super_admin_user} = User.by_username(@test_super_admin_username) {:ok, admin_user} = User.by_username(@test_admin_username) {:ok, global_mod_user} = User.by_username(@test_global_mod_username)