Delegate can_access_page? to CheckPagePermission

- UI uses same rules as plug (reserved 'new', own/linked path checks)
This commit is contained in:
Moritz 2026-01-30 10:22:31 +01:00
parent ea1d01fcea
commit a1fe36b7f2

View file

@ -30,6 +30,7 @@ defmodule MvWeb.Authorization do
"""
alias Mv.Authorization.PermissionSets
alias MvWeb.Plugs.CheckPagePermission
@doc """
Checks if user has permission for an action on a resource.
@ -111,16 +112,9 @@ defmodule MvWeb.Authorization do
def can_access_page?(nil, _page_path), do: false
def can_access_page?(user, page_path) do
# Convert verified route to string if needed
# Delegate to plug logic so UI uses same rules (reserved "new", own/linked path checks).
page_path_str = if is_binary(page_path), do: page_path, else: to_string(page_path)
with %{role: %{permission_set_name: ps_name}} when not is_nil(ps_name) <- user,
{:ok, ps_atom} <- PermissionSets.permission_set_name_to_atom(ps_name),
permissions <- PermissionSets.get_permissions(ps_atom) do
page_matches?(permissions.pages, page_path_str)
else
_ -> false
end
CheckPagePermission.user_can_access_page?(user, page_path_str, router: MvWeb.Router)
end
# Check if scope allows access to record
@ -172,33 +166,6 @@ defmodule MvWeb.Authorization do
end
end
# Check if page path matches any allowed pattern
defp page_matches?(allowed_pages, requested_path) do
Enum.any?(allowed_pages, fn pattern ->
cond do
pattern == "*" -> true
pattern == requested_path -> true
String.contains?(pattern, ":") -> match_pattern?(pattern, requested_path)
true -> false
end
end)
end
# Match dynamic route pattern
defp match_pattern?(pattern, path) do
pattern_segments = String.split(pattern, "/", trim: true)
path_segments = String.split(path, "/", trim: true)
if length(pattern_segments) == length(path_segments) do
Enum.zip(pattern_segments, path_segments)
|> Enum.all?(fn {pattern_seg, path_seg} ->
String.starts_with?(pattern_seg, ":") or pattern_seg == path_seg
end)
else
false
end
end
# Extract resource name from module
defp get_resource_name(resource) when is_atom(resource) do
resource |> Module.split() |> List.last()