styling, require a code for prompts, admin privs, ordering, filtering, jump-to-page

This commit is contained in:
2022-09-07 16:25:42 -04:00
parent 7990246675
commit eefd11d85a
52 changed files with 2827 additions and 300 deletions

View File

@@ -0,0 +1,67 @@
defmodule DiffuserWeb.Plugs.PublicIp do
@moduledoc "Get public IP address of request from x-forwarded-for header"
def init(opts), do: opts
def call(%{assigns: %{ip: _}} = conn, _opts), do: conn
def call(conn, _opts) do
process(conn, Plug.Conn.get_req_header(conn, "x-forwarded-for"))
end
def process(%{remote_ip: remote_ip} = conn, []) do
Plug.Conn.assign(conn, :ip, to_string(:inet_parse.ntoa(remote_ip)))
end
def process(conn, vals) do
# Rewrite standard remote_ip field with value from header
ip_address = get_ip_address(conn, vals)
# See https://hexdocs.pm/plug/Plug.Conn.html
conn = %{conn | remote_ip: ip_address}
Plug.Conn.assign(conn, :ip, to_string(:inet_parse.ntoa(ip_address)))
end
defp get_ip_address(conn, vals)
defp get_ip_address(%{remote_ip: remote_ip}, []), do: remote_ip
defp get_ip_address(%{remote_ip: remote_ip} = _conn, [val | _]) do
# Split into multiple values
comps =
val
|> String.split(~r{\s*,\s*}, trim: true)
# Get rid of "unknown" values
|> Enum.filter(&(&1 != "unknown"))
# Split IP from port, if any
|> Enum.map(&hd(String.split(&1, ":")))
# Filter out blanks
|> Enum.filter(&(&1 != ""))
# Parse address into :inet.ip_address tuple
|> Enum.map(&parse_address(&1))
# Elminate internal IP addreses, e.g. 192.168.1.1
|> Enum.filter(&is_public_ip(&1))
case comps do
[] -> remote_ip
[comp | _] -> comp
end
end
defp parse_address(ip) do
case :inet.parse_ipv4strict_address(to_charlist(ip)) do
{:ok, ip_address} -> ip_address
{:error, :einval} -> :einval
end
end
defp is_public_ip(ip_address) do
case ip_address do
{10, _, _, _} -> false
{192, 168, _, _} -> false
{172, second, _, _} when second >= 16 and second <= 31 -> false
{127, 0, 0, _} -> false
{_, _, _, _} -> true
:einval -> false
end
end
end

View File

@@ -0,0 +1,37 @@
defmodule DiffuserWeb.Plugs.UserAuth do
use DiffuserWeb, :controller
import Plug.Conn
alias Diffuser.Accounts
alias Diffuser.Repo
def init(default), do: default
def call(%{remote_ip: remote_ip} = conn, _) do
remote_ip = remote_ip |> :inet_parse.ntoa() |> to_string()
case get_session(conn, :user) do
nil ->
with {:ok, user} <- Accounts.create_user(%{ip_address: remote_ip}) do
put_session(conn, :user, user |> Repo.preload(votes: [:prompt_request]))
else
{:error, _changeset} -> put_session(conn, :user, nil)
end
%Accounts.User{ip_address: user_ip} = user ->
with false <- user_ip == remote_ip,
{:ok, user} <- Accounts.update_user(user, %{ip_address: remote_ip}) do
conn |> put_session(:user, user |> Repo.preload(votes: [:prompt_request]))
else
true ->
put_session(
conn,
:user,
Accounts.get_user!(user.id) |> Repo.preload(votes: [:prompt_request])
)
_ ->
put_session(conn, :user, nil)
end
end
end
end

View File

@@ -0,0 +1,16 @@
defmodule DiffuserWeb.Plugs.ValidateAdmin do
use DiffuserWeb, :controller
import Plug.Conn
def init(default), do: default
def call(%{remote_ip: remote_ip} = conn, _) do
remote_ip = remote_ip |> :inet_parse.ntoa() |> to_string()
if remote_ip == "127.0.0.1" do
conn |> put_session(:is_admin, true)
else
conn |> put_session(:is_admin, false)
end
end
end