Commit 768939f0 authored by Mikko Ahlroth's avatar Mikko Ahlroth

Add support for specifying acceptable hosts

parent 774ff987
......@@ -4,73 +4,87 @@ defmodule Tilastokeskus.Reception.Routes.PageView do
require Logger
@impl Raxx.Server
def handle_request(req, _state) do
at = DateTime.utc_now()
addr = get_addr(req)
ua = parse_ua(req)
{referrer, referrer_noq, referrer_domain} = parse_referrer(req)
def handle_request(req, state) do
body = URI.decode_query(req.body || "")
{path, path_noq, host} = parse_url(body)
screen_w = Map.get(body, "screen_width")
screen_h = Map.get(body, "screen_height")
tz_offset = Map.get(body, "tz_offset")
{city, country} = get_geoip(addr)
# Run in one transaction to avoid multiple DB checkouts
{:ok, response} =
Tilastokeskus.Archive.Repo.transaction(fn ->
session = get_session(req)
cset =
PageView.changeset(
%PageView{},
%{
at: at,
session: session,
addr: addr,
path: path,
path_noq: path_noq,
host: host,
referrer: referrer,
referrer_noq: referrer_noq,
referrer_domain: referrer_domain,
ua: unknown_2_str(ua.user_agent),
ua_name: unknown_2_str(ua.client.name),
ua_version: unknown_2_str(ua.client.version),
os_name: unknown_2_str(ua.os.name),
os_version: unknown_2_str(ua.os.version),
device_type: unknown_2_str(ua.device.type),
screen_w: screen_w,
screen_h: screen_h,
tz_offset: tz_offset,
loc_city: city,
loc_country: country
}
)
case Tilastokeskus.Archive.Utils.PageView.create(cset) do
{:ok, _} ->
response(200)
|> set_header("content-type", "application/json")
|> set_body(Jason.encode!(%{ok: "OK"}))
|> Raxx.Session.SignedCookie.embed(
session.id,
Tilastokeskus.Reception.Session.config()
{path, path_noq, host, authority} = parse_url(body)
if not check_host(host, state) do
response(400)
|> set_header("content-type", "application/json")
|> set_body(Jason.encode!(%{error: "Host not allowed."}))
else
at = DateTime.utc_now()
addr = get_addr(req)
ua = parse_ua(req)
{referrer, referrer_noq, referrer_domain} = parse_referrer(req)
screen_w = Map.get(body, "screen_width")
screen_h = Map.get(body, "screen_height")
tz_offset = Map.get(body, "tz_offset")
{city, country} = get_geoip(addr)
# Run in one transaction to avoid multiple DB checkouts
{:ok, response} =
Tilastokeskus.Archive.Repo.transaction(fn ->
session = get_session(req)
cset =
PageView.changeset(
%PageView{},
%{
at: at,
session: session,
addr: addr,
path: path,
path_noq: path_noq,
host: authority,
referrer: referrer,
referrer_noq: referrer_noq,
referrer_domain: referrer_domain,
ua: unknown_2_str(ua.user_agent),
ua_name: unknown_2_str(ua.client.name),
ua_version: unknown_2_str(ua.client.version),
os_name: unknown_2_str(ua.os.name),
os_version: unknown_2_str(ua.os.version),
device_type: unknown_2_str(ua.device.type),
screen_w: screen_w,
screen_h: screen_h,
tz_offset: tz_offset,
loc_city: city,
loc_country: country
}
)
{:error, err} ->
Logger.error("Error saving pageview: #{inspect(err)}")
case Tilastokeskus.Archive.Utils.PageView.create(cset) do
{:ok, _} ->
response(200)
|> set_header("content-type", "application/json")
|> set_body(Jason.encode!(%{ok: "OK"}))
|> Raxx.Session.SignedCookie.embed(
session.id,
Tilastokeskus.Reception.Session.config()
)
{:error, err} ->
Logger.error("Error saving pageview: #{inspect(err)}")
response(500)
|> set_header("content-type", "application/json")
|> set_body(Jason.encode!(%{error: "ERROR"}))
end
end)
response(500)
|> set_header("content-type", "application/json")
|> set_body(Jason.encode!(%{error: "ERROR"}))
end
end)
response
end
end
defp check_host(host, state) do
allowed_hosts = Keyword.get(state, :hosts, [])
response
# If no hosts are specified, everything goes
Enum.empty?(allowed_hosts) || Enum.member?(allowed_hosts, host)
end
defp get_addr(req) do
......@@ -166,6 +180,7 @@ defmodule Tilastokeskus.Reception.Routes.PageView do
{
if(not is_nil(parsed.query), do: "#{parsed.path}?#{parsed.query}", else: parsed.path),
parsed.path,
parsed.host,
parsed.authority
}
end
......
......@@ -9,11 +9,12 @@ defmodule Tilastokeskus.Application do
:ok = Tilastokeskus.Reception.Session.validate_config()
port = (System.get_env("PORT") || "1971") |> String.to_integer()
hosts = get_hosts()
# List all child processes to be supervised
children = [
{Tilastokeskus.Archive.Repo, []},
{Tilastokeskus.Reception.Router, [port: port]}
{Tilastokeskus.Reception.Router, [[hosts: hosts], [port: port]]}
]
# See https://hexdocs.pm/elixir/Supervisor.html
......@@ -21,4 +22,11 @@ defmodule Tilastokeskus.Application do
opts = [strategy: :one_for_one, name: Tilastokeskus.Supervisor]
Supervisor.start_link(children, opts)
end
defp get_hosts() do
case System.get_env("TILASTOKESKUS_HOSTS") do
nil -> ""
hosts -> String.split(hosts, ",")
end
end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment