diff --git a/.env.example b/.env.example index e2700ab..8cd3cdc 100644 --- a/.env.example +++ b/.env.example @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -export HERE_API=YOUR API KEY +export NOMINATIM_URL=https://nominatim.openstreetmap.org export ZENFLOWS_URL="http://fcos.interfacer.dyne.org:9000" export PORT=8080 export INBOX=INBOX URL diff --git a/README.md b/README.md index e430b4d..1cc202f 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,6 @@ along with this program. If not, see . A unifying HTTP proxy for services used by [the interfacer-gui project](https://github.com/interfacerproject/interfacer-gui) - ## Services The front-end project, @@ -31,72 +30,68 @@ implemented for the Interfacer Project. At the moment, the services implemented are: -* Zenflows - a [zenflows](https://github.com/interfacerproject/zenflows) - instance. It's the main back-end service.; -* Inbox - a [zenflows-inbox](https://github.com/interfacerproject/zenflows-inbox) - instance. It provides notifications and implements a subset of ActivityPub. -* Wallet - a [zenflows-wallet](https://github.com/interfacerproject/zenflows-wallet) - instance. It powers the economic model behind the Interfacer - project. It is an interface between interfacer-gui and planetmint. -* Location Autocomplition - provided by - [Here API](https://autocomplete.search.hereapi.com/v1/autocomplete) +- Zenflows - a [zenflows](https://github.com/interfacerproject/zenflows) + instance. It's the main back-end service.; +- Inbox - a [zenflows-inbox](https://github.com/interfacerproject/zenflows-inbox) + instance. It provides notifications and implements a subset of ActivityPub. +- Wallet - a [zenflows-wallet](https://github.com/interfacerproject/zenflows-wallet) + instance. It powers the economic model behind the Interfacer + project. It is an interface between interfacer-gui and planetmint. +- Location Autocomplition - provided by + [Nominatim](https://nominatim.openstreetmap.org/search) to autocomplete location/place names on the map; -* Location Lookup - provided by - [Here API](https://lookup.search.hereapi.com/v1/lookup) to lookup +- Location Lookup - provided by + [Nominatim](https://nominatim.openstreetmap.org/lookup) to lookup location/place names on the map; - ## Bulding and executing You may either choose to build from source, build and use the Docker image, or just use the pre-built Docker image on -https://ghcr.io/interfacerproject/interfacer-gateway. A set of +https://ghcr.io/interfacerproject/interfacer-gateway. A set of Ansible scripts are also provided, which could be used as well. Building from source with Go might be a bit work due to the -dependencies. Building from source with Docker or using Ansible +dependencies. Building from source with Docker or using Ansible is recommended, as they will be easier to get started. Each option is detailed in the following sections. - ### Building from source with Go Bulding with Go from the source requires Go version 1.18 or later. If you have the Go toolchain and a POSIX-compliant make(1) implementation installed (GNU make(1) works), you can just run: - make + make which builds a the service as the executable named `interfacer-gateway`. - ### Building from source with Docker -Building with Docker requires nothing but the Docker tooling. The +Building with Docker requires nothing but the Docker tooling. The image produced will have all the dependencies needed to run this service. To build the image, you can run: - docker build -t interfacer-gateway:latest . + docker build -t interfacer-gateway:latest . -which will name the image "interfacer-gateway". Then, you can run: +which will name the image "interfacer-gateway". Then, you can run: - docker run --rm -p PORT:8080 \ - -e ZENFLOWS_URL=http://url-to-zenflows-instance \ + docker run --rm -p PORT:8080 \ + -e ZENFLOWS_URL=http://url-to-zenflows-instance \ -e INTERFACER_DPP_URL=http://url-to-interfacer-dpp-instance \ - -e INBOX_URL=http://url-to-inbox-instance \ - -e WALLET_URL=http://url-to-wallet-instance \ - -e OSH_URL=http://url-to-osh-instance \ - -e HERE_KEY=api-key-for-here-dot-com \ - zenflows-osh - -to start the service on port `PORT`. The service will require you -to provide the environment variables listed above. The variables + -e INBOX_URL=http://url-to-inbox-instance \ + -e WALLET_URL=http://url-to-wallet-instance \ + -e OSH_URL=http://url-to-osh-instance \ + -e NOMINATIM_URL=https://nominatim.openstreetmap.org \ + zenflows-osh + +to start the service on port `PORT`. The service will require you +to provide the environment variables listed above. The variables are descriped on the section "Configuration". - ### Using the pre-built image You may choose to just use the pre-built image, which is found at @@ -104,17 +99,17 @@ https://ghcr.io/interfacerproject/interfacer-gateway. To use that image, you can run: - docker run --rm -p PORT:8080 \ - -e ZENFLOWS_URL=http://url-to-zenflows-instance \ + docker run --rm -p PORT:8080 \ + -e ZENFLOWS_URL=http://url-to-zenflows-instance \ -e INTERFACER_DPP_URL=http://url-to-interfacer-dpp-instance \ - -e INBOX_URL=http://url-to-inbox-instance \ - -e WALLET_URL=http://url-to-wallet-instance \ - -e OSH_URL=http://url-to-osh-instance \ - -e HERE_KEY=api-key-for-here-dot-com \ - ghcr.io/interfacerproject/interfacer-gateway + -e INBOX_URL=http://url-to-inbox-instance \ + -e WALLET_URL=http://url-to-wallet-instance \ + -e OSH_URL=http://url-to-osh-instance \ + -e NOMINATIM_URL=https://nominatim.openstreetmap.org \ + ghcr.io/interfacerproject/interfacer-gateway which will start the service on port `PORT`. The service will require -you to provide the environment variables listed above. The variables +you to provide the environment variables listed above. The variables are descriped on the section "Configuration". You may optionally use a docker-compose.yml template like this as well: @@ -135,7 +130,7 @@ services: INBOX_URL: http://url-to-inbox-instance WALLET_URL: http://url-to-wallet-instance OSH_URL: http://url-to-osh-instance - HERE_KEY: api-key-for-here-dot-com + NOMINATIM_URL: https://nominatim.openstreetmap.org stdin_open: true tty: true ``` @@ -150,18 +145,18 @@ The deployment use docker-compose with a template that groups all the services r It can be started writing the `hosts.yaml` and running `make install` inside the `devops` directory. In the `hosts.yaml` one has to provide: - - `domain_name`: the FQDN of the server - - `zenflows`: URL for the zenflows instanc3 - - `ifacer_log`: directory in which we want to save the logs - - `port`: port for proxy on `localhost` - - `here_api`: URL for the API of here.com - - `inbox_port`: port for inbox on `localhost` - - `wallet_port`: port for wallet on `localhost` - - `zenflows_sk`: secret key for a user in zenflows - - `zenflows_user`: username of the same user in zenflows -Warning: currently we are deploying in a LAN with private address, so you may need to modify `docker-compose.yaml.j2` +- `domain_name`: the FQDN of the server +- `zenflows`: URL for the zenflows instanc3 +- `ifacer_log`: directory in which we want to save the logs +- `port`: port for proxy on `localhost` +- `nominatim_url`: base URL for the Nominatim instance (optional, defaults to https://nominatim.openstreetmap.org) +- `inbox_port`: port for inbox on `localhost` +- `wallet_port`: port for wallet on `localhost` +- `zenflows_sk`: secret key for a user in zenflows +- `zenflows_user`: username of the same user in zenflows +Warning: currently we are deploying in a LAN with private address, so you may need to modify `docker-compose.yaml.j2` ## Configuration @@ -169,24 +164,24 @@ The configuration is done by providing environment variables. Here is the list of them: -* `ZENFLOWS_URL` - the URL of +- `ZENFLOWS_URL` - the URL of [the zenflows instance](https://github.com/interfacerproject/zenflows) to which the requests will be proxied; -* `INTERFACER_DPP_URL` - the URL of +- `INTERFACER_DPP_URL` - the URL of [the interfacer-dpp instance](https://github.com/interfacerproject/interfacer-dpp) to which the requests will be proxied; -* `INBOX_URL` - the URL of +- `INBOX_URL` - the URL of [the zenflows-inbox instance](https://github.com/interfacerproject/zenflows-inbox) to which the requests should be proxied; -* `WALLET_URL` - the URL of +- `WALLET_URL` - the URL of [the zenflows-wallet instance](https://github.com/interfacerproject/zenflows-wallet) to which the requests should be proxied; -* `OSH_URL` - the URL of +- `OSH_URL` - the URL of [the zenflows-osh instance](https://github.com/interfacerproject/zenflows-osh) to which the requests should be proxied; -* `HERE_KEY` - the API key required by the Here API. More on that - at: https://developer.here.com/documentation. - +- `NOMINATIM_URL` - the base URL of the Nominatim geocoding service. + Defaults to `https://nominatim.openstreetmap.org` if not set. + Set this to a self-hosted instance if needed. ## Usage @@ -196,12 +191,11 @@ service with the identifier of the service. For instance, let's assume that "/foo/and/whatnot" is supposed to be sent to the "BAR" service, and the identifier of the service "BAR" -is "bar". Then, the clients of the gateway sends the request to +is "bar". Then, the clients of the gateway sends the request to the gateway with the url "/bar/foo/andwhatnot", assuming that -everything will be sent to the service "BAR". As such, the provided +everything will be sent to the service "BAR". As such, the provided HTTP methods and headers will be forwarded to the service "BAR". - ## Examples See the subdirectory `examples/`. diff --git a/config/config.go b/config/config.go index e5c3ea1..8e7293a 100644 --- a/config/config.go +++ b/config/config.go @@ -55,9 +55,11 @@ type Config struct { // https://github.com/interfacerproject/zenflows-osh OSHURL *url.URL - // The opaque API key of here.com. More on that at: - // https://developer.here.com/documentation - HereKey string + // NominatimURL is the base URL of the Nominatim instance used + // for location search and lookup. Defaults to the public + // instance at https://nominatim.openstreetmap.org when + // NOMINATIM_URL is not set. + NominatimURL *url.URL } // NewEnv() fetches configuration options from the environment. If @@ -106,11 +108,18 @@ func NewEnv() (*Config, error) { } c.OSHURL = u - s = os.Getenv("HERE_KEY") + s = os.Getenv("NOMINATIM_URL") if s == "" { - return nil, errors.New(`"HERE_KEY" must be provided`) + s = "https://nominatim.openstreetmap.org" } - c.HereKey = s + u, err = url.Parse(s) + if err != nil || u.Scheme == "" || u.Host == "" { + return nil, errors.New(`"NOMINATIM_URL" is malformed`) + } + if u.Scheme != "http" && u.Scheme != "https" { + return nil, errors.New(`"NOMINATIM_URL" is malformed: invalid scheme; must be http(s)`) + } + c.NominatimURL = &url.URL{Scheme: u.Scheme, Host: u.Host, Path: "/"} return c, nil } diff --git a/devops/roles/proxy-docker-compose/templates/docker-compose.yml.j2 b/devops/roles/proxy-docker-compose/templates/docker-compose.yml.j2 index e6a2d30..4cd89da 100644 --- a/devops/roles/proxy-docker-compose/templates/docker-compose.yml.j2 +++ b/devops/roles/proxy-docker-compose/templates/docker-compose.yml.j2 @@ -23,7 +23,7 @@ services: - "{{ port }}:80" environment: ZENFLOWS_URL: "{{ zenflows }}" - HERE_KEY: "{{ here_api }}" + NOMINATIM_URL: "{{ nominatim_url | default('https://nominatim.openstreetmap.org') }}" ADDR: :80 INBOX_URL: "http://inbox" WALLET_URL: "http://wallet" diff --git a/main.go b/main.go index 472b9d1..723d0c3 100644 --- a/main.go +++ b/main.go @@ -20,15 +20,16 @@ import ( "bytes" "errors" "fmt" - "github.com/interfacerproject/interfacer-gateway/config" - "github.com/interfacerproject/interfacer-gateway/logger" - "github.com/sirupsen/logrus" "io" "net" "net/http" "net/url" "os" "time" + + "github.com/interfacerproject/interfacer-gateway/config" + "github.com/interfacerproject/interfacer-gateway/logger" + "github.com/sirupsen/logrus" ) var conf *config.Config @@ -82,20 +83,16 @@ var proxiedHosts = []ProxiedHost{ ProxiedHost{ name: "location-autocomplete", buildUrl: func(u *url.URL) *url.URL { - values := u.Query() - values.Add("apiKey", conf.HereKey) - currentUrl, _ := url.Parse("https://autocomplete.search.hereapi.com/v1/autocomplete") - currentUrl.RawQuery = values.Encode() + currentUrl := conf.NominatimURL.JoinPath("/search") + currentUrl.RawQuery = u.RawQuery return currentUrl }, }, ProxiedHost{ name: "location-lookup", buildUrl: func(u *url.URL) *url.URL { - values := u.Query() - values.Add("apiKey", conf.HereKey) - currentUrl, _ := url.Parse("https://lookup.search.hereapi.com/v1/lookup") - currentUrl.RawQuery = values.Encode() + currentUrl := conf.NominatimURL.JoinPath("/lookup") + currentUrl.RawQuery = u.RawQuery return currentUrl }, },