Skip to content

Commit

Permalink
Make maximum identifier length configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
the-last-pastafarian committed Nov 22, 2023
1 parent 1ebddd9 commit 6b6d693
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 16 deletions.
3 changes: 2 additions & 1 deletion server/config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ config :field_hub,
valid_file_variants: [:thumbnail_image, :original_image],
file_index_cache_name: :file_info,
file_max_size: 1_000_000_000,
user_tokens_cache_name: :user_tokens
user_tokens_cache_name: :user_tokens,
max_project_identifier_length: 30

# Configure esbuild (the version is required)
config :esbuild,
Expand Down
3 changes: 2 additions & 1 deletion server/lib/field_hub/project.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ defmodule FieldHub.Project do
require Logger

@variant_types Application.compile_env(:field_hub, :valid_file_variants)
@identifier_length Application.compile_env(:field_hub, :max_project_identifier_length)

@moduledoc """
Bundles functions concerning Field projects in FieldHub.
Expand All @@ -29,7 +30,7 @@ defmodule FieldHub.Project do
- `project_identifier` the project's name
"""
def create(project_identifier) do
if String.length(project_identifier) > 30 do
if String.length(project_identifier) > @identifier_length do
:invalid_name
else
project_identifier
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ defmodule FieldHubWeb.Api.ProjectController do

alias FieldHubWeb.Api.StatusView

@identifier_length Application.compile_env(:field_hub, :max_project_identifier_length)

def index(%{assigns: %{current_user: user_name}} = conn, _params) do
render(conn, "list.json", %{projects: Project.get_all_for_user(user_name)})
end
Expand Down Expand Up @@ -60,7 +62,8 @@ defmodule FieldHubWeb.Api.ProjectController do
|> put_status(:bad_request)
|> put_view(StatusView)
|> render(%{
error: "Invalid project name: Identifier can have 30 characters maximum and requires valid name, regex: /^[a-z][a-z0-9_$()+/-]*$/"
error:
"Invalid project name: Identifier can have #{@identifier_length} characters maximum and requires valid name, regex: /^[a-z][a-z0-9_$()+/-]*$/"
})

_ ->
Expand Down
6 changes: 4 additions & 2 deletions server/lib/field_hub_web/live/project_create_live.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ defmodule FieldHubWeb.ProjectCreateLive do

require Logger

@identifier_length Application.compile_env(:field_hub, :max_project_identifier_length)

def mount(_params, %{"user_token" => user_token} = _session, socket) do
user_name =
user_token
Expand Down Expand Up @@ -85,7 +87,7 @@ defmodule FieldHubWeb.ProjectCreateLive do
identifier == "" ->
:identifier_empty

String.length(identifier) > 30 ->
String.length(identifier) > @identifier_length ->
:identifier_invalid

not String.match?(identifier, ~r/^[a-z][a-z0-9_$()+\/-]*$/) ->
Expand Down Expand Up @@ -127,7 +129,7 @@ defmodule FieldHubWeb.ProjectCreateLive do
defp format_issue(:identifier_invalid),
do: """
Please provide a valid project identifier. The identifier must begin with a lower case letter (a-z), followed by any of the following letters:
Lowercase characters (a-z), Digits (0-9) or any of the characters _, $, (, ), +, -, and /. The maximum length is 30 characters.
Lowercase characters (a-z), Digits (0-9) or any of the characters _, $, (, ), +, -, and /. The maximum length is #{@identifier_length} characters.
"""

defp format_issue(:identifier_taken),
Expand Down
6 changes: 4 additions & 2 deletions server/test/field_hub/project_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ defmodule FieldHub.ProjectTest do
@user_name "test_user"
@user_password "test_password"

@identifier_length Application.compile_env(:field_hub, :max_project_identifier_length)

test "exists?/1 correctly returns false" do
assert false == Project.exists?(@project)
end
Expand Down Expand Up @@ -54,8 +56,8 @@ defmodule FieldHub.ProjectTest do
assert %{database: :unknown_project, file_store: []} = Project.delete(identifier)
end

test "can not create project with more than 30 characters in name" do
long_project_identifier = "aasdfasdfasdfasdfasdfasdfsadfsadfasdfasdfasdfdfsad"
test "can not create project with more than the maximum characters in identifier" do
long_project_identifier = String.duplicate("a", @identifier_length + 1)

on_exit(fn ->
Project.delete(long_project_identifier)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ defmodule FieldHubWeb.Api.ProjectControllerTest do
@independent_user_password "test_password"
@independent_user_auth "Basic #{Base.encode64("#{@independent_user_name}:#{@independent_user_password}")}"

@identifier_length Application.compile_env(:field_hub, :max_project_identifier_length)
setup_all %{} do
TestHelper.create_user(@independent_user_name, @independent_user_password)

Expand Down Expand Up @@ -138,25 +139,34 @@ defmodule FieldHubWeb.Api.ProjectControllerTest do

response = Jason.decode!(conn.resp_body)

expected_reason =
"Invalid project name: Identifier can have #{@identifier_length} characters maximum and requires valid name, regex: /^[a-z][a-z0-9_$()+/-]*$/"

assert %{
"reason" => "Invalid project name: Identifier can have 30 characters maximum and requires valid name, regex: /^[a-z][a-z0-9_$()+/-]*$/"
"reason" => ^expected_reason
} = response
end

test "POST /projects/:project with project identifier longer that 30 characters returns :bad_request", %{
conn: conn
} do
test "POST /projects/:project with a project identifier exceeding the maximum characters returns :bad_request",
%{
conn: conn
} do
long_project_identifier = String.duplicate("a", @identifier_length + 1)

conn =
conn
|> put_req_header("authorization", TestHelper.get_admin_basic_auth())
|> post("/projects/asdfasdfasdfasdfasdfdfasdfasdfasfdasfdasdf")
|> post("/projects/#{long_project_identifier}")

assert conn.status == 400

response = Jason.decode!(conn.resp_body)

expected_reason =
"Invalid project name: Identifier can have #{@identifier_length} characters maximum and requires valid name, regex: /^[a-z][a-z0-9_$()+/-]*$/"

assert %{
"reason" => "Invalid project name: Identifier can have 30 characters maximum and requires valid name, regex: /^[a-z][a-z0-9_$()+/-]*$/"
"reason" => ^expected_reason
} = response
end
end
Expand Down
7 changes: 4 additions & 3 deletions server/test/field_hub_web/live/project_create_live_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ defmodule FieldHubWeb.ProjectCreateLiveTest do
@endpoint FieldHubWeb.Endpoint

@admin_user Application.compile_env(:field_hub, :couchdb_admin_name)
@project "test_project"
@identifier_length Application.compile_env(:field_hub, :max_project_identifier_length)

@project "test_project"
test "redirect to login if not authenticated", %{conn: conn} do
# Test the authentication plug (http)
assert {:error, {:redirect, %{flash: _, to: "/ui/session/new"}}} =
Expand Down Expand Up @@ -201,15 +202,15 @@ defmodule FieldHubWeb.ProjectCreateLiveTest do
assert html =~ "Please provide a valid project identifier."
end

test "project identifier longer than 30 characters throws a warning", %{
test "project identifier longer than the maximum characters throws a warning", %{
conn: conn
} do
{:ok, view, _html_on_mount} = live(conn, "/ui/projects/create")

html =
view
|> element("form")
|> render_change(%{identifier: "asdfasdfasdfasdfasdfasdfffffffggggf"})
|> render_change(%{identifier: String.duplicate("a", @identifier_length + 1)})

assert html =~ "Please provide a valid project identifier."
end
Expand Down

0 comments on commit 6b6d693

Please sign in to comment.