From 617083cce7956d8a27b3737c1ae857d080498935 Mon Sep 17 00:00:00 2001 From: chris Date: Fri, 24 May 2019 12:40:25 -0400 Subject: [PATCH] Pass all requests to OpenStack through proxy server --- src/Rest/Helpers.elm | 53 +++++++++++++++++++++++++++++++++++++++++--- src/Rest/Rest.elm | 18 ++++++++++----- 2 files changed, 62 insertions(+), 9 deletions(-) diff --git a/src/Rest/Helpers.elm b/src/Rest/Helpers.elm index ba098233..9d7de4ca 100644 --- a/src/Rest/Helpers.elm +++ b/src/Rest/Helpers.elm @@ -1,4 +1,4 @@ -module Rest.Helpers exposing (openstackCredentialedRequest) +module Rest.Helpers exposing (openstackCredentialedRequest, proxyifyRequest) import Helpers.Helpers as Helpers import Http @@ -6,6 +6,7 @@ import OpenStack.Types as OSTypes import Task import Time import Types.Types as TT +import Url httpRequestMethodStr : TT.HttpRequestMethod -> String @@ -31,12 +32,16 @@ openstackCredentialedRequest project method url requestBody expect = -} let + ( proxyUrl, headers ) = + -- TODO don't hard-code proxy server URL, specify it in global defaults or something + proxyifyRequest "https://dogfood.exosphere.app/proxy" url + tokenToRequestCmd : OSTypes.AuthTokenString -> Cmd TT.Msg tokenToRequestCmd token = Http.request { method = httpRequestMethodStr method - , headers = [ Http.header "X-Auth-Token" token ] - , url = url + , headers = [ Http.header "X-Auth-Token" token ] ++ headers + , url = proxyUrl , body = requestBody , expect = expect , timeout = Nothing @@ -46,3 +51,45 @@ openstackCredentialedRequest project method url requestBody expect = Task.perform (\posixTime -> TT.ProjectMsg (Helpers.getProjectId project) (TT.ValidateTokenForCredentialedRequest tokenToRequestCmd posixTime)) Time.now + + +proxyifyRequest : String -> String -> ( String, List Http.Header ) +proxyifyRequest proxyServerUrl requestUrlStr = + {- Returns URL to pass to proxy server, and a list of HTTP headers -} + let + {- Todo should we pass Url.Url around the app instead of URLs as strings? The following string-to-URL conversion is ugly -} + defaultUrl = + Url.Url + Url.Https + "thisisbroken.pizza" + Nothing + "" + Nothing + Nothing + + requestUrl = + Url.fromString requestUrlStr + |> Maybe.withDefault defaultUrl + + origHost = + requestUrl.host + + origPort = + requestUrl.port_ |> Maybe.withDefault 443 + + pathQuery = + case requestUrl.query of + Just query -> + requestUrl.path ++ "?" ++ query + + Nothing -> + requestUrl.path + + proxyRequestUrl = + proxyServerUrl ++ pathQuery + in + ( proxyRequestUrl + , [ Http.header "exo-proxy-orig-host" origHost + , Http.header "exo-proxy-orig-port" <| String.fromInt origPort + ] + ) diff --git a/src/Rest/Rest.elm b/src/Rest/Rest.elm index 8de706a7..7fc367db 100644 --- a/src/Rest/Rest.elm +++ b/src/Rest/Rest.elm @@ -128,18 +128,24 @@ requestAuthToken creds = ] ) ] - in - {- https://stackoverflow.com/questions/44368340/get-request-headers-from-http-request -} - Http.request - { method = "POST" - , headers = [] - , url = + + authUrl = if String.contains "/auth/tokens" creds.authUrl then -- We previously expected users to provide "/auth/tokens" to be in the Keystone Auth URL; this case statement avoids breaking the app for users who still have that creds.authUrl else creds.authUrl ++ "/auth/tokens" + + ( proxyUrl, headers ) = + -- TODO don't hard-code proxy server URL, specify it in global defaults or something + proxyifyRequest "https://dogfood.exosphere.app/proxy" authUrl + in + {- https://stackoverflow.com/questions/44368340/get-request-headers-from-http-request -} + Http.request + { method = "POST" + , headers = headers + , url = proxyUrl , body = Http.jsonBody requestBody {- Todo handle no response? -}