Skip to content

Commit

Permalink
Merge pull request #1012 from OpenFn/downloads-auth-hot-fix
Browse files Browse the repository at this point in the history
Downloads auth hot fix
  • Loading branch information
stuartc authored Aug 4, 2023
2 parents 5cf83f6 + 1d060e4 commit 5555a8e
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ and this project adheres to
- Fixed issue where entering a placeholder name through the form would result an
in unsaveable workflow
[#1001](https://github.com/OpenFn/Lightning/issues/1001)
- Ensure the DownloadController checks for authentication and authorisation.

## [v0.7.0-pre5] - 2023-07-28

Expand Down
34 changes: 24 additions & 10 deletions lib/lightning_web/controllers/downloads_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,32 @@ defmodule LightningWeb.DownloadsController do
use LightningWeb, :controller

alias Lightning.Projects
alias Lightning.Policies.ProjectUsers
alias Lightning.Policies.Permissions

action_fallback(LightningWeb.FallbackController)

def download_project_yaml(conn, %{"id" => id}) do
{:ok, yaml} = Projects.export_project(:yaml, id)
with %Projects.Project{} = project <-
Lightning.Projects.get_project(id) || {:error, :not_found},
:ok <-
ProjectUsers
|> Permissions.can(
:access_project,
conn.assigns.current_user,
project
) do
{:ok, yaml} = Projects.export_project(:yaml, id)

conn
|> put_resp_content_type("text/yaml")
|> put_resp_header(
"content-disposition",
"attachment; filename=\"project-#{id}.yaml\""
)
|> put_root_layout(false)
|> put_flash(:info, "Project yaml exported successfully")
|> send_resp(200, yaml)
conn
|> put_resp_content_type("text/yaml")
|> put_resp_header(
"content-disposition",
"attachment; filename=\"project-#{id}.yaml\""
)
|> put_root_layout(false)
|> put_flash(:info, "Project yaml exported successfully")
|> send_resp(200, yaml)
end
end
end
2 changes: 1 addition & 1 deletion lib/lightning_web/controllers/fallback_controller.ex
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ defmodule LightningWeb.FallbackController do
conn
|> put_status(:unauthorized)
|> put_view(LightningWeb.ErrorView)
|> render(:"401")
|> render(:"401", error: %{error: :unauthirized})
end

def call(conn, {:error, :forbidden}) do
Expand Down
3 changes: 2 additions & 1 deletion lib/lightning_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ defmodule LightningWeb.Router do
get "/authenticate/callback", OidcController, :new
get "/authenticate/:provider", OidcController, :show
get "/authenticate/:provider/callback", OidcController, :new
get "/download/yaml", DownloadsController, :download_project_yaml
end

## JSON API
Expand Down Expand Up @@ -85,6 +84,8 @@ defmodule LightningWeb.Router do
UserConfirmationController,
:confirm_email

get "/download/yaml", DownloadsController, :download_project_yaml

live_session :settings, on_mount: LightningWeb.InitAssigns do
live "/settings", SettingsLive.Index, :index

Expand Down
40 changes: 40 additions & 0 deletions test/lightning_web/controllers/download_controller_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
defmodule LightningWeb.DownloadControllerTest do
use LightningWeb.ConnCase, async: true

import Lightning.Factories

describe "GET /downloads/yaml" do
setup :register_and_log_in_user
setup :create_project_for_current_user

test "correctly renders a project yaml", %{conn: conn, project: project} do
response =
conn
|> get(~p"/download/yaml?#{%{id: project.id}}")

assert response.status == 200
end

test "renders a 404? when the user isn't authorized", %{conn: conn} do
p = insert(:project)

response =
conn
|> get(~p"/download/yaml?#{%{id: p.id}}")

assert response.status == 401
end
end

describe "when not logged in" do
test "redirects when you are not logged in", %{conn: conn} do
response =
conn
|> get("/download/yaml?id=#{Ecto.UUID.generate()}")

assert response.status == 302
assert response.resp_headers
assert {"location", "/users/log_in"} in response.resp_headers
end
end
end

0 comments on commit 5555a8e

Please sign in to comment.