Skip to content

Commit

Permalink
Merge pull request #1495 from GSA/staging
Browse files Browse the repository at this point in the history
Staging to Production
  • Loading branch information
jairoanaya authored Dec 30, 2024
2 parents 827862d + afc02fc commit 432296a
Show file tree
Hide file tree
Showing 18 changed files with 196 additions and 868 deletions.
1 change: 1 addition & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@
- [ ] If you have DB migration, it is a "safe" migration and you've confirmed it can be rolled back.
- [ ] If applicable, Controllers modified contain appropriate authorization plugs
- [ ] This PR has been reviewed by at least one other team member.
- [ ] Build has been approved for deployment in CircleCI.

2 changes: 1 addition & 1 deletion assets/client/src/components/ChallengeTab.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export const ChallengeTab = ({ label, downloadsLabel, section, challenge, childr
if (label === "Overview") {
return (
<div className="float-right" id="challenge-link">
<input id={`challenge-link-text-${section}`} className="opacity-0" defaultValue={window.location.href} />
<input id={`challenge-link-text-${section}`} aria-hidden="true" className="opacity-0" defaultValue={window.location.href} />
<button id="challenge-link-btn" className="usa-button usa-button--unstyled text-decoration-none" onClick={handleCopyLink}>
<svg className="usa-icon" aria-hidden="true" focusable="false" role="img" style={{fill: "#FA9441", height: "21px", width: "21px", position: "relative", top: "5px", right: "5px"}}>
<title id="copy-share-link">ChallengeGov follow challenges</title>
Expand Down
2 changes: 0 additions & 2 deletions assets/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,11 @@
"axios": "^0.21.2",
"chart.js": "^3.2.1",
"chokidar": "^3.3.1",
"create-react-app": "^5.0.1",
"file-loader": "^6.2.0",
"inputmask": "^5.0.5",
"jquery": "^3.3.1",
"moment": "^2.27.0",
"moment-timezone": "^0.5.31",
"node-quill-converter": "^0.3.3",
"node-sass": "^8.0.0",
"phoenix": "file:../deps/phoenix",
"phoenix_html": "file:../deps/phoenix_html",
Expand Down
871 changes: 62 additions & 809 deletions assets/yarn.lock

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions lib/challenge_gov/challenges.ex
Original file line number Diff line number Diff line change
Expand Up @@ -755,6 +755,33 @@ defmodule ChallengeGov.Challenges do
end
end

@doc """
Checks if a user is allowed to view the submissions
"""

def allowed_to_view_submission(user, challenge) do
if is_challenge_manager?(user, challenge) do
if Security.validate_gov_mil?(user.email) do
{:ok, challenge}
else
{:error, :not_permitted}
end
else
if Accounts.has_admin_access?(user) do
{:ok, challenge}
else
{:error, :not_permitted}
end
end
end

def is_allowed_to_view_submission?(user = %{role: "challenge_manager"}),
do: Security.validate_gov_mil?(user.email)

def is_allowed_to_view_submission?(user = %{role: "super_admin"}), do: true

def is_allowed_to_view_submission?(user = %{role: "admin"}), do: true

def allowed_to_submit?(%{role: "super_admin"}), do: true

def allowed_to_submit?(%{role: "admin"}), do: true
Expand Down
29 changes: 29 additions & 0 deletions lib/challenge_gov/security.ex
Original file line number Diff line number Diff line change
Expand Up @@ -209,4 +209,33 @@ defmodule ChallengeGov.Security do
|> String.split(",")
|> Enum.map(&String.trim/1)
end

# functions to control non-gov challenge manager
def intercept_challenge_manager_ng(original_track) do
%{
original_track
| originator_role:
is_challenge_manager_ng(
original_track.originator_role,
original_track.originator_identifier
)
}
end

# check role challenge_manager & .gov or .mil email account
def is_challenge_manager_ng(originator_role = "challenge_manager", originator_identifier) do
if validate_gov_mil?(originator_identifier) do
originator_role
else
"challenge_manager_ng"
end
end

def is_challenge_manager_ng(originator_role = _, originator_identifier) do
originator_role
end

def validate_gov_mil?(email) do
String.ends_with?(email, [".gov", ".mil"])
end
end
4 changes: 3 additions & 1 deletion lib/challenge_gov/security_logs.ex
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ defmodule ChallengeGov.SecurityLogs do
def track(params) do
Logger.info("Audit event #{params[:action]}", log_type: "audit", params: params)

params = Security.intercept_challenge_manager_ng(original_track = params)

%SecurityLog{}
|> SecurityLog.changeset(params)
|> Repo.insert()
Expand Down Expand Up @@ -55,7 +57,7 @@ defmodule ChallengeGov.SecurityLogs do
action: "session_duration",
details: %{duration: duration},
originator_id: user.id,
originator_role: user.role,
originator_role: Security.is_challenge_manager_ng(user.role, user.email),
originator_identifier: user.email,
originator_remote_ip: remote_ip
})
Expand Down
20 changes: 20 additions & 0 deletions lib/challenge_gov/submissions.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ defmodule ChallengeGov.Submissions do
alias ChallengeGov.Submissions.Submission
alias ChallengeGov.SubmissionExports
alias Stein.Filter
alias ChallengeGov.Security

def all(opts \\ []) do
Submission
Expand Down Expand Up @@ -301,6 +302,25 @@ defmodule ChallengeGov.Submissions do
submission.manager_id && !submission.review_verified
end

def allowed_to_view_submission(user, submission) do
if user.role == "challenge_manager" do
if Security.validate_gov_mil?(user.email) do
{:ok, submission}
else
{:error, :not_permitted}
end
end
end

def is_allowed_to_view_submission?(user = %{role: "challenge_manager"}),
do: Security.validate_gov_mil?(user.email)

def is_allowed_to_view_submission?(user = %{role: "super_admin"}), do: true

def is_allowed_to_view_submission?(user = %{role: "admin"}), do: true

def is_allowed_to_view_submission?(user = %{role: "solver"}), do: true

defp send_submission_review_email(user, phase, submission) do
user
|> Emails.submission_review(phase, submission)
Expand Down
44 changes: 25 additions & 19 deletions lib/web/controllers/submission_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -149,30 +149,36 @@ defmodule Web.SubmissionController do

def show(conn, params = %{"id" => _id}) do
%{current_user: user, current_submission: submission, page: page} = conn.assigns

filter = Map.get(params, "filter", %{})
sort = Map.get(params, "sort", %{})
# only challenge manager with .mil or .gov is allowed
if Submissions.is_allowed_to_view_submission?(user) do
with {:ok, phase} <- Phases.get(submission.phase_id),
{:ok, challenge} <- Challenges.get(submission.challenge_id) do
conn
|> assign(:user, user)
|> assign(:challenge, challenge)
|> assign(:phase, phase)
|> assign(:submission, submission)
|> assign(:page, page)
|> assign(:filter, filter)
|> assign(:sort, sort)
|> assign(:action, action_name(conn))
|> assign(:navbar_text, submission.title || "Submission #{submission.id}")
|> is_closed(phase.end_date)

with {:ok, phase} <- Phases.get(submission.phase_id),
{:ok, challenge} <- Challenges.get(submission.challenge_id) do
# |> render("show.html")
else
{:error, :not_found} ->
conn
|> put_flash(:error, "Submission not found")
|> redirect_by_user_type(user, submission)
end
else
conn
|> assign(:user, user)
|> assign(:challenge, challenge)
|> assign(:phase, phase)
|> assign(:submission, submission)
|> assign(:page, page)
|> assign(:filter, filter)
|> assign(:sort, sort)
|> assign(:action, action_name(conn))
|> assign(:navbar_text, submission.title || "Submission #{submission.id}")
|> is_closed(phase.end_date)

# |> render("show.html")
else
{:error, :not_found} ->
conn
|> put_flash(:error, "Submission not found")
|> redirect_by_user_type(user, submission)
|> put_flash(:error, "You are not allowed to view submissions")
|> redirect(to: Routes.challenge_path(conn, :index))
end
end

Expand Down
14 changes: 0 additions & 14 deletions lib/web/templates/challenge/_challenge_manager_banner.html.eex

This file was deleted.

1 change: 0 additions & 1 deletion lib/web/templates/challenge/show.html.eex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
%{text: "Challenges", route: Routes.challenge_path(@conn, :index)},
%{text: @challenge.title}
])%>
<%= render Web.ChallengeView, "_challenge_manager_banner.html", user: @user %>
<div class="row">
<div class="col-sm-6">
<div class="font-ui-xl text-dark padding-1">
Expand Down
1 change: 0 additions & 1 deletion lib/web/templates/challenge/wizard.html.eex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
%{text: "Challenges", route: Routes.challenge_path(@conn, :index)},
%{text: @challenge && @challenge.title || "New"}
])%>
<%= render Web.ChallengeView, "_challenge_manager_banner.html", user: @user %>
<div class="row mb-2">
<div class="col-sm-6">
<h1 class="m-0 text-dark">
Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ defmodule ChallengeGov.MixProject do
{:oban, "~> 2.3"},
{:phoenix, "~> 1.5.7"},
{:phoenix_ecto, "~> 4.0"},
{:phoenix_html, "~> 2.14.3"},
{:phoenix_html, "~> 3.1.0", override: true},
{:phoenix_live_reload, "~> 1.3", only: :dev},
{:phoenix_live_view, "~> 0.15.4", override: true},
{:phoenix_pubsub, "~> 2.0"},
Expand Down
6 changes: 3 additions & 3 deletions mix.lock
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,13 @@
"parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"},
"phoenix": {:hex, :phoenix, "1.5.14", "2d5db884be496eefa5157505ec0134e66187cb416c072272420c5509d67bf808", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.13 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.1.2 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "207f1aa5520320cbb7940d7ff2dde2342162cf513875848f88249ea0ba02fef7"},
"phoenix_ecto": {:hex, :phoenix_ecto, "4.4.0", "0672ed4e4808b3fbed494dded89958e22fb882de47a97634c0b13e7b0b5f7720", [:mix], [{:ecto, "~> 3.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "09864e558ed31ee00bd48fcc1d4fc58ae9678c9e81649075431e69dbabb43cc1"},
"phoenix_html": {:hex, :phoenix_html, "2.14.3", "51f720d0d543e4e157ff06b65de38e13303d5778a7919bcc696599e5934271b8", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "efd697a7fff35a13eeeb6b43db884705cba353a1a41d127d118fda5f90c8e80f"},
"phoenix_html": {:hex, :phoenix_html, "3.1.0", "0b499df05aad27160d697a9362f0e89fa0e24d3c7a9065c2bd9d38b4d1416c09", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "0c0a98a2cefa63433657983a2a594c7dee5927e4391e0f1bfd3a151d1def33fc"},
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.4.1", "2aff698f5e47369decde4357ba91fc9c37c6487a512b41732818f2204a8ef1d3", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "9bffb834e7ddf08467fe54ae58b5785507aaba6255568ae22b4d46e2bb3615ab"},
"phoenix_live_view": {:hex, :phoenix_live_view, "0.15.7", "09720b8e5151b3ca8ef739cd7626d4feb987c69ba0b509c9bbdb861d5a365881", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.5.7", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 0.5", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3a756cf662420272d0f1b3b908cce5222163b5a95aa9bab404f9d29aff53276e"},
"phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.1", "ba04e489ef03763bf28a17eb2eaddc2c20c6d217e2150a61e3298b0f4c2012b5", [:mix], [], "hexpm", "81367c6d1eea5878ad726be80808eb5a787a23dee699f96e72b1109c57cdd8d9"},
"plug": {:hex, :plug, "1.14.0", "ba4f558468f69cbd9f6b356d25443d0b796fbdc887e03fa89001384a9cac638f", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "bf020432c7d4feb7b3af16a0c2701455cbbbb95e5b6866132cb09eb0c29adc14"},
"plug": {:hex, :plug, "1.16.1", "40c74619c12f82736d2214557dedec2e9762029b2438d6d175c5074c933edc9d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2 or ~> 2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a13ff6b9006b03d7e33874945b2755253841b238c34071ed85b0e86057f8cddc"},
"plug_cowboy": {:hex, :plug_cowboy, "2.6.0", "d1cf12ff96a1ca4f52207c5271a6c351a4733f413803488d75b70ccf44aebec2", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "073cf20b753ce6682ed72905cd62a2d4bd9bad1bf9f7feb02a1b8e525bd94fa6"},
"plug_crypto": {:hex, :plug_crypto, "1.2.3", "8f77d13aeb32bfd9e654cb68f0af517b371fb34c56c9f2b58fe3df1235c1251a", [:mix], [], "hexpm", "b5672099c6ad5c202c45f5a403f21a3411247f164e4a8fab056e5cd8a290f4a2"},
"plug_crypto": {:hex, :plug_crypto, "1.2.5", "918772575e48e81e455818229bf719d4ab4181fcbf7f85b68a35620f78d89ced", [:mix], [], "hexpm", "26549a1d6345e2172eb1c233866756ae44a9609bd33ee6f99147ab3fd87fd842"},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm", "fec8660eb7733ee4117b85f55799fd3833eb769a6df71ccf8903e8dc5447cfce"},
"poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"},
"porcelain": {:hex, :porcelain, "2.0.3", "2d77b17d1f21fed875b8c5ecba72a01533db2013bd2e5e62c6d286c029150fdc", [:mix], [], "hexpm", "dc996ab8fadbc09912c787c7ab8673065e50ea1a6245177b0c24569013d23620"},
Expand Down
6 changes: 3 additions & 3 deletions test/web/controllers/challenge_controller_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ defmodule Web.ChallengeControllerTest do
[
60,
"p",
[[32, "class", 61, 34, "h4 mb-0", 34]],
[32, "class", 61, 34, "h4 mb-0", 34],
62,
"Challenge Removed from Queue",
60,
Expand Down Expand Up @@ -595,7 +595,7 @@ defmodule Web.ChallengeControllerTest do
safe: [
60,
"p",
[[32, "class", 61, 34, "h4 mb-0", 34]],
[32, "class", 61, 34, "h4 mb-0", 34],
62,
"Challenge updated",
60,
Expand All @@ -613,7 +613,7 @@ defmodule Web.ChallengeControllerTest do
[
60,
"a",
[[32, "href", 61, 34, "/challenges/#{challenge.id}/bulletin/new", 34]],
[32, "href", 61, 34, "/challenges/#{challenge.id}/bulletin/new", 34],
62,
"Govdelivery",
60,
Expand Down
2 changes: 1 addition & 1 deletion test/web/controllers/phase_winner_controller_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ defmodule Web.PhaseWinnerControllerTest do
conn = get(conn, Routes.challenge_path(conn, :show, challenge.id))

assert html_response(conn, 200) =~
"<a class=\"usa-button disabled\" href=\"#\" disabled>Add winners</a>"
"<a class=\"usa-button disabled\" disabled href=\"#\">Add winners</a>"
end

test "success: show only closed phases", %{conn: conn} do
Expand Down
14 changes: 6 additions & 8 deletions test/web/controllers/saved_challenge_controller_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -180,14 +180,12 @@ defmodule Web.SavedChallengeControllerTest do
60,
"a",
[
[
32,
"href",
61,
34,
"http://localhost:4001/?challenge=#{challenge.id}",
34
]
32,
"href",
61,
34,
"http://localhost:4001/?challenge=#{challenge.id}",
34
],
62,
"here",
Expand Down
18 changes: 14 additions & 4 deletions test/web/views/message_context_view_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ defmodule Web.MessageContextViewTest do
[
60,
"a",
[[32, "href", 61, 34, "/challenges/#{challenge.id}", 34]],
[32, "href", 61, 34, "/challenges/#{challenge.id}", 34],
62,
"Test challenge",
60,
Expand Down Expand Up @@ -54,7 +54,7 @@ defmodule Web.MessageContextViewTest do
[
60,
"a",
[[32, "href", 61, 34, "/challenges/#{challenge.id}", 34]],
[32, "href", 61, 34, "/challenges/#{challenge.id}", 34],
62,
"Test challenge",
60,
Expand Down Expand Up @@ -223,8 +223,18 @@ defmodule Web.MessageContextViewTest do
60,
"a",
[
[32, "class", 61, 34, "usa-button me-3", 34],
[32, "href", 61, 34, "/messages/new?context=challenge", 34]
32,
"class",
61,
34,
"usa-button me-3",
34,
32,
"href",
61,
34,
"/messages/new?context=challenge",
34
],
62,
"New Message",
Expand Down

0 comments on commit 432296a

Please sign in to comment.