diff --git a/lib/mobilizon/config.ex b/lib/mobilizon/config.ex index 553f6e3d3..7b2ebbe48 100644 --- a/lib/mobilizon/config.ex +++ b/lib/mobilizon/config.ex @@ -30,6 +30,10 @@ defmodule Mobilizon.Config do @spec instance_email_reply_to :: String.t() def instance_email_reply_to, do: instance_config()[:email_reply_to] + @spec instance_user_agent :: String.t() + def instance_user_agent, + do: "#{instance_name()} #{instance_hostname()} - Mobilizon #{Mix.Project.config()[:version]}" + @spec get(module | atom) :: any def get(key), do: get(key, nil) diff --git a/lib/service/geospatial/addok.ex b/lib/service/geospatial/addok.ex index b209ec0d9..8dd88d52b 100644 --- a/lib/service/geospatial/addok.ex +++ b/lib/service/geospatial/addok.ex @@ -5,6 +5,7 @@ defmodule Mobilizon.Service.Geospatial.Addok do alias Mobilizon.Addresses.Address alias Mobilizon.Service.Geospatial.Provider + alias Mobilizon.Config require Logger @@ -18,12 +19,14 @@ defmodule Mobilizon.Service.Geospatial.Addok do """ @spec geocode(String.t(), keyword()) :: list(Address.t()) def geocode(lon, lat, options \\ []) do + user_agent = Keyword.get(options, :user_agent, Config.instance_user_agent()) + headers = [{"User-Agent", user_agent}] url = build_url(:geocode, %{lon: lon, lat: lat}, options) Logger.debug("Asking addok for addresses with #{url}") with {:ok, %HTTPoison.Response{status_code: 200, body: body}} <- - HTTPoison.get(url), + HTTPoison.get(url, headers), {:ok, %{"features" => features}} <- Poison.decode(body) do process_data(features) end @@ -35,11 +38,13 @@ defmodule Mobilizon.Service.Geospatial.Addok do """ @spec search(String.t(), keyword()) :: list(Address.t()) def search(q, options \\ []) do + user_agent = Keyword.get(options, :user_agent, Config.instance_user_agent()) + headers = [{"User-Agent", user_agent}] url = build_url(:search, %{q: q}, options) Logger.debug("Asking addok for addresses with #{url}") with {:ok, %HTTPoison.Response{status_code: 200, body: body}} <- - HTTPoison.get(url), + HTTPoison.get(url, headers), {:ok, %{"features" => features}} <- Poison.decode(body) do process_data(features) end diff --git a/lib/service/geospatial/map_quest.ex b/lib/service/geospatial/map_quest.ex index 1c45a38b6..084836a03 100644 --- a/lib/service/geospatial/map_quest.ex +++ b/lib/service/geospatial/map_quest.ex @@ -11,6 +11,7 @@ defmodule Mobilizon.Service.Geospatial.MapQuest do alias Mobilizon.Addresses.Address alias Mobilizon.Service.Geospatial.Provider + alias Mobilizon.Config require Logger @@ -29,6 +30,8 @@ defmodule Mobilizon.Service.Geospatial.MapQuest do api_key = Keyword.get(options, :api_key, @api_key) limit = Keyword.get(options, :limit, 10) open_data = Keyword.get(options, :open_data, true) + user_agent = Keyword.get(options, :user_agent, Config.instance_user_agent()) + headers = [{"User-Agent", user_agent}] prefix = if open_data, do: "open", else: "www" @@ -38,7 +41,8 @@ defmodule Mobilizon.Service.Geospatial.MapQuest do HTTPoison.get( "https://#{prefix}.mapquestapi.com/geocoding/v1/reverse?key=#{api_key}&location=#{ lat - },#{lon}&maxResults=#{limit}" + },#{lon}&maxResults=#{limit}", + headers ), {:ok, %{"results" => results, "info" => %{"statuscode" => 0}}} <- Poison.decode(body) do results |> Enum.map(&process_data/1) @@ -54,6 +58,8 @@ defmodule Mobilizon.Service.Geospatial.MapQuest do """ @spec search(String.t(), keyword()) :: list(Address.t()) def search(q, options \\ []) do + user_agent = Keyword.get(options, :user_agent, Config.instance_user_agent()) + headers = [{"User-Agent", user_agent}] limit = Keyword.get(options, :limit, 10) api_key = Keyword.get(options, :api_key, @api_key) @@ -71,7 +77,7 @@ defmodule Mobilizon.Service.Geospatial.MapQuest do Logger.debug("Asking MapQuest for addresses with #{url}") with {:ok, %HTTPoison.Response{status_code: 200, body: body}} <- - HTTPoison.get(url), + HTTPoison.get(url, headers), {:ok, %{"results" => results, "info" => %{"statuscode" => 0}}} <- Poison.decode(body) do results |> Enum.map(&process_data/1) else diff --git a/lib/service/geospatial/nominatim.ex b/lib/service/geospatial/nominatim.ex index 47dda84f7..c00e0e936 100644 --- a/lib/service/geospatial/nominatim.ex +++ b/lib/service/geospatial/nominatim.ex @@ -5,6 +5,7 @@ defmodule Mobilizon.Service.Geospatial.Nominatim do alias Mobilizon.Addresses.Address alias Mobilizon.Service.Geospatial.Provider + alias Mobilizon.Config require Logger @@ -19,11 +20,13 @@ defmodule Mobilizon.Service.Geospatial.Nominatim do """ @spec geocode(String.t(), keyword()) :: list(Address.t()) def geocode(lon, lat, options \\ []) do + user_agent = Keyword.get(options, :user_agent, Config.instance_user_agent()) + headers = [{"User-Agent", user_agent}] url = build_url(:geocode, %{lon: lon, lat: lat}, options) Logger.debug("Asking Nominatim for geocode with #{url}") with {:ok, %HTTPoison.Response{status_code: 200, body: body}} <- - HTTPoison.get(url), + HTTPoison.get(url, headers), {:ok, body} <- Poison.decode(body) do [process_data(body)] end @@ -35,11 +38,13 @@ defmodule Mobilizon.Service.Geospatial.Nominatim do """ @spec search(String.t(), keyword()) :: list(Address.t()) def search(q, options \\ []) do + user_agent = Keyword.get(options, :user_agent, Config.instance_user_agent()) + headers = [{"User-Agent", user_agent}] url = build_url(:search, %{q: q}, options) Logger.debug("Asking Nominatim for addresses with #{url}") with {:ok, %HTTPoison.Response{status_code: 200, body: body}} <- - HTTPoison.get(url), + HTTPoison.get(url, headers), {:ok, body} <- Poison.decode(body) do body |> Enum.map(fn entry -> process_data(entry) end) |> Enum.filter(& &1) end diff --git a/lib/service/geospatial/photon.ex b/lib/service/geospatial/photon.ex index 7bf11131d..df954305c 100644 --- a/lib/service/geospatial/photon.ex +++ b/lib/service/geospatial/photon.ex @@ -5,6 +5,7 @@ defmodule Mobilizon.Service.Geospatial.Photon do alias Mobilizon.Addresses.Address alias Mobilizon.Service.Geospatial.Provider + alias Mobilizon.Config require Logger @@ -20,11 +21,13 @@ defmodule Mobilizon.Service.Geospatial.Photon do """ @spec geocode(number(), number(), keyword()) :: list(Address.t()) def geocode(lon, lat, options \\ []) do + user_agent = Keyword.get(options, :user_agent, Config.instance_user_agent()) + headers = [{"User-Agent", user_agent}] url = build_url(:geocode, %{lon: lon, lat: lat}, options) Logger.debug("Asking photon for reverse geocoding with #{url}") with {:ok, %HTTPoison.Response{status_code: 200, body: body}} <- - HTTPoison.get(url), + HTTPoison.get(url, headers), {:ok, %{"features" => features}} <- Poison.decode(body) do process_data(features) end @@ -36,11 +39,13 @@ defmodule Mobilizon.Service.Geospatial.Photon do """ @spec search(String.t(), keyword()) :: list(Address.t()) def search(q, options \\ []) do + user_agent = Keyword.get(options, :user_agent, Config.instance_user_agent()) + headers = [{"User-Agent", user_agent}] url = build_url(:search, %{q: q}, options) Logger.debug("Asking photon for addresses with #{url}") with {:ok, %HTTPoison.Response{status_code: 200, body: body}} <- - HTTPoison.get(url), + HTTPoison.get(url, headers), {:ok, %{"features" => features}} <- Poison.decode(body) do process_data(features) end diff --git a/test/mobilizon/service/geospatial/addok_test.exs b/test/mobilizon/service/geospatial/addok_test.exs index d81cfaab4..7dbf948dc 100644 --- a/test/mobilizon/service/geospatial/addok_test.exs +++ b/test/mobilizon/service/geospatial/addok_test.exs @@ -7,20 +7,31 @@ defmodule Mobilizon.Service.Geospatial.AddokTest do alias Mobilizon.Addresses.Address alias Mobilizon.Service.Geospatial.Addok + alias Mobilizon.Config + + @httpoison_headers [ + {"User-Agent", + "#{Config.instance_name()} #{Config.instance_hostname()} - Mobilizon #{ + Mix.Project.config()[:version] + }"} + ] @endpoint get_in(Application.get_env(:mobilizon, Addok), [:endpoint]) @fake_endpoint "https://domain.tld" describe "search address" do test "produces a valid search address" do - with_mock HTTPoison, get: fn _url -> "{}" end do + with_mock HTTPoison, get: fn _url, _headers -> "{}" end do Addok.search("10 Rue Jangot") - assert_called(HTTPoison.get("#{@endpoint}/search/?q=10%20Rue%20Jangot&limit=10")) + + assert_called( + HTTPoison.get("#{@endpoint}/search/?q=10%20Rue%20Jangot&limit=10", @httpoison_headers) + ) end end test "produces a valid search address with options" do - with_mock HTTPoison, get: fn _url -> "{}" end do + with_mock HTTPoison, get: fn _url, _headers -> "{}" end do Addok.search("10 Rue Jangot", endpoint: @fake_endpoint, limit: 5, @@ -28,7 +39,10 @@ defmodule Mobilizon.Service.Geospatial.AddokTest do ) assert_called( - HTTPoison.get("#{@fake_endpoint}/search/?q=10%20Rue%20Jangot&limit=5&lat=49&lon=12") + HTTPoison.get( + "#{@fake_endpoint}/search/?q=10%20Rue%20Jangot&limit=5&lat=49&lon=12", + @httpoison_headers + ) ) end end diff --git a/test/mobilizon/service/geospatial/map_quest_test.exs b/test/mobilizon/service/geospatial/map_quest_test.exs index 1176ef316..00d535cae 100644 --- a/test/mobilizon/service/geospatial/map_quest_test.exs +++ b/test/mobilizon/service/geospatial/map_quest_test.exs @@ -7,6 +7,14 @@ defmodule Mobilizon.Service.Geospatial.MapQuestTest do alias Mobilizon.Addresses.Address alias Mobilizon.Service.Geospatial.MapQuest + alias Mobilizon.Config + + @httpoison_headers [ + {"User-Agent", + "#{Config.instance_name()} #{Config.instance_hostname()} - Mobilizon #{ + Mix.Project.config()[:version] + }"} + ] describe "search address" do test "without API Key triggers an error" do @@ -17,7 +25,7 @@ defmodule Mobilizon.Service.Geospatial.MapQuestTest do test "produces a valid search address with options" do with_mock HTTPoison, - get: fn _url -> + get: fn _url, _headers -> {:ok, %HTTPoison.Response{ status_code: 200, @@ -32,7 +40,8 @@ defmodule Mobilizon.Service.Geospatial.MapQuestTest do assert_called( HTTPoison.get( - "https://open.mapquestapi.com/geocoding/v1/address?key=toto&location=10%20Rue%20Jangot&maxResults=5" + "https://open.mapquestapi.com/geocoding/v1/address?key=toto&location=10%20Rue%20Jangot&maxResults=5", + @httpoison_headers ) ) end diff --git a/test/mobilizon/service/geospatial/nominatim_test.exs b/test/mobilizon/service/geospatial/nominatim_test.exs index e436afbe3..04bec7da4 100644 --- a/test/mobilizon/service/geospatial/nominatim_test.exs +++ b/test/mobilizon/service/geospatial/nominatim_test.exs @@ -7,11 +7,19 @@ defmodule Mobilizon.Service.Geospatial.NominatimTest do alias Mobilizon.Addresses.Address alias Mobilizon.Service.Geospatial.Nominatim + alias Mobilizon.Config + + @httpoison_headers [ + {"User-Agent", + "#{Config.instance_name()} #{Config.instance_hostname()} - Mobilizon #{ + Mix.Project.config()[:version] + }"} + ] describe "search address" do test "produces a valid search address with options" do with_mock HTTPoison, - get: fn _url -> + get: fn _url, _headers -> {:ok, %HTTPoison.Response{status_code: 200, body: "[]"}} end do Nominatim.search("10 Rue Jangot", @@ -21,7 +29,8 @@ defmodule Mobilizon.Service.Geospatial.NominatimTest do assert_called( HTTPoison.get( - "https://nominatim.openstreetmap.org/search?format=jsonv2&q=10%20Rue%20Jangot&limit=5&accept-language=fr&addressdetails=1" + "https://nominatim.openstreetmap.org/search?format=jsonv2&q=10%20Rue%20Jangot&limit=5&accept-language=fr&addressdetails=1", + @httpoison_headers ) ) end diff --git a/test/mobilizon/service/geospatial/photon_test.exs b/test/mobilizon/service/geospatial/photon_test.exs index 630035c60..009bccdb4 100644 --- a/test/mobilizon/service/geospatial/photon_test.exs +++ b/test/mobilizon/service/geospatial/photon_test.exs @@ -7,11 +7,19 @@ defmodule Mobilizon.Service.Geospatial.PhotonTest do alias Mobilizon.Addresses.Address alias Mobilizon.Service.Geospatial.Photon + alias Mobilizon.Config + + @httpoison_headers [ + {"User-Agent", + "#{Config.instance_name()} #{Config.instance_hostname()} - Mobilizon #{ + Mix.Project.config()[:version] + }"} + ] describe "search address" do test "produces a valid search address with options" do with_mock HTTPoison, - get: fn _url -> + get: fn _url, _headers -> {:ok, %HTTPoison.Response{status_code: 200, body: "{\"features\": []"}} end do Photon.search("10 Rue Jangot", @@ -20,7 +28,10 @@ defmodule Mobilizon.Service.Geospatial.PhotonTest do ) assert_called( - HTTPoison.get("https://photon.komoot.de/api/?q=10%20Rue%20Jangot&lang=fr&limit=5") + HTTPoison.get( + "https://photon.komoot.de/api/?q=10%20Rue%20Jangot&lang=fr&limit=5", + @httpoison_headers + ) ) end end