Fetch and store values from secrets.

This commit is contained in:
Dillon Kearns 2019-10-24 08:26:41 -07:00
parent 8e2c4b8348
commit 69e465d511
3 changed files with 149 additions and 95 deletions

View File

@ -30,7 +30,7 @@ import Pages.ImagePath as ImagePath
import Pages.Manifest as Manifest
import Pages.PagePath as PagePath exposing (PagePath)
import Pages.StaticHttpRequest as StaticHttpRequest
import Secrets
import Secrets exposing (Secrets)
import Set
import StaticHttp
import Url exposing (Url)
@ -96,7 +96,7 @@ successCodec =
type Effect pathKey
= NoEffect
| SendJsData (ToJsPayload pathKey)
| FetchHttp Secrets.UrlWithSecrets
| FetchHttp Secrets Secrets.UrlWithSecrets
| Batch (List (Effect pathKey))
@ -116,7 +116,7 @@ type alias Flags =
type alias Model =
{ staticResponses : StaticResponses }
{ staticResponses : StaticResponses, secrets : Secrets }
type alias ModelDetails userModel metadata view =
@ -220,12 +220,7 @@ perform cliMsgConstructor toJsPort effect =
|> List.map (perform cliMsgConstructor toJsPort)
|> Cmd.batch
FetchHttp urlWithSecrets ->
let
realSecrets =
-- TODO @@@@@
Secrets.empty
in
FetchHttp realSecrets urlWithSecrets ->
Http.get
{ url = urlWithSecrets realSecrets |> Result.withDefault "TODO" -- TODO handle error
, expect =
@ -241,80 +236,96 @@ perform cliMsgConstructor toJsPort effect =
init toModel contentCache siteMetadata config cliMsgConstructor flags =
(case contentCache of
Ok _ ->
case contentCache |> ContentCache.pagesWithErrors of
Just pageErrors ->
let
requests =
siteMetadata
|> Result.andThen
(\metadata ->
staticResponseForPage metadata config.view
case Decode.decodeValue (Decode.field "secrets" Secrets.decoder) flags |> Debug.log "SECRETS" of
Ok secrets ->
(case contentCache of
Ok _ ->
case contentCache |> ContentCache.pagesWithErrors of
Just pageErrors ->
let
requests =
siteMetadata
|> Result.andThen
(\metadata ->
staticResponseForPage metadata config.view
)
staticResponses : StaticResponses
staticResponses =
case requests of
Ok okRequests ->
staticResponsesInit okRequests
Err errors ->
Dict.empty
in
case Decode.decodeValue (Decode.field "secrets" Decode.string) flags of
Ok _ ->
( Model staticResponses secrets |> toModel
, SendJsData
(Errors
(mapKeys
(\key -> "/" ++ String.join "/" key)
pageErrors
)
)
)
staticResponses : StaticResponses
staticResponses =
Err error ->
( Model staticResponses Secrets.empty |> toModel
, SendJsData
(Errors (Dict.fromList [ ( "", "Failed to parse flags: " ++ Decode.errorToString error ) ]))
)
Nothing ->
let
requests =
siteMetadata
|> Result.andThen
(\metadata ->
staticResponseForPage metadata config.view
)
staticResponses : StaticResponses
staticResponses =
case requests of
Ok okRequests ->
staticResponsesInit okRequests
Err errors ->
Dict.empty
in
case requests of
Ok okRequests ->
staticResponsesInit okRequests
( Model staticResponses secrets |> toModel, performStaticHttpRequests secrets okRequests )
-- |> Cmd.map cliMsgConstructor
Err errors ->
Dict.empty
in
( Model staticResponses |> toModel
( Model staticResponses secrets |> toModel, NoEffect )
Err error ->
( Model Dict.empty secrets |> toModel
, SendJsData
(Errors
(mapKeys
(\key -> "/" ++ String.join "/" key)
pageErrors
error
)
)
)
Nothing ->
let
requests =
siteMetadata
|> Result.andThen
(\metadata ->
staticResponseForPage metadata config.view
)
staticResponses : StaticResponses
staticResponses =
case requests of
Ok okRequests ->
staticResponsesInit okRequests
Err errors ->
Dict.empty
in
case requests of
Ok okRequests ->
( Model staticResponses |> toModel, performStaticHttpRequests okRequests )
-- |> Cmd.map cliMsgConstructor
Err errors ->
( Model staticResponses |> toModel, NoEffect )
-- (Errors error)
-- (Json.Encode.object
-- [ ( "errors", encodeErrors error )
-- , ( "manifest", Manifest.toJson config.manifest )
-- ]
-- )
)
Err error ->
( Model Dict.empty |> toModel
( Model Dict.empty Secrets.empty |> toModel
, SendJsData
(Errors
(mapKeys
(\key -> "/" ++ String.join "/" key)
error
)
)
(Errors (Dict.fromList [ ( "", "Failed to parse flags: " ++ Decode.errorToString error ) ]))
)
-- (Errors error)
-- (Json.Encode.object
-- [ ( "errors", encodeErrors error )
-- , ( "manifest", Manifest.toJson config.manifest )
-- ]
-- )
)
update :
@ -382,12 +393,8 @@ update siteMetadata config msg model =
)
performStaticHttpRequests : List ( PagePath pathKey, StaticHttp.Request a ) -> Effect pathKey
performStaticHttpRequests staticRequests =
let
secrets =
Secrets.empty
in
performStaticHttpRequests : Secrets -> List ( PagePath pathKey, StaticHttp.Request a ) -> Effect pathKey
performStaticHttpRequests secrets staticRequests =
staticRequests
|> List.map
(\( pagePath, StaticHttpRequest.Request ( urls, lookup ) ) ->
@ -408,7 +415,7 @@ performStaticHttpRequests staticRequests =
-- TODO prevent duplicates... can't because Set needs comparable
-- |> Set.fromList
-- |> Set.toList
|> List.map FetchHttp
|> List.map (FetchHttp secrets)
|> Batch
@ -434,15 +441,9 @@ staticResponsesUpdate newEntry staticResponses =
let
realUrls =
urls
|> List.filterMap
|> List.map
(\urlBuilder ->
case urlBuilder Secrets.empty of
Ok url ->
Just url
Err _ ->
-- @@@@@@@@@ TODO handle error here
Nothing
Secrets.useFakeSecrets urlBuilder
)
includesUrl =

View File

@ -1,6 +1,7 @@
module Secrets exposing (..)
import Dict exposing (Dict)
import Json.Decode as Decode exposing (Decoder)
type alias UrlWithSecrets =
@ -40,3 +41,9 @@ get name secretsData =
Nothing ->
Err <| "Couldn't find secret `" ++ name ++ "`"
decoder : Decoder Secrets
decoder =
Decode.dict Decode.string
|> Decode.map Secrets

View File

@ -12,7 +12,7 @@ import Pages.Internal.Platform.Cli as Main exposing (..)
import Pages.Manifest as Manifest
import Pages.PagePath as PagePath
import ProgramTest exposing (ProgramTest)
import Secrets
import Secrets exposing (Secrets)
import SimulatedEffect.Cmd
import SimulatedEffect.Http
import SimulatedEffect.Ports
@ -27,7 +27,7 @@ all =
\() ->
start
[ ( []
, { url = "https://api.github.com/repos/dillonkearns/elm-pages", decoder = Decode.succeed () }
, { url = \_ -> Ok "https://api.github.com/repos/dillonkearns/elm-pages", decoder = Decode.succeed () }
)
]
|> ProgramTest.simulateHttpOk
@ -57,10 +57,10 @@ all =
\() ->
start
[ ( [ "elm-pages" ]
, { url = "https://api.github.com/repos/dillonkearns/elm-pages", decoder = Decode.succeed () }
, { url = \_ -> Ok "https://api.github.com/repos/dillonkearns/elm-pages", decoder = Decode.succeed () }
)
, ( [ "elm-pages-starter" ]
, { url = "https://api.github.com/repos/dillonkearns/elm-pages-starter", decoder = Decode.succeed () }
, { url = \_ -> Ok "https://api.github.com/repos/dillonkearns/elm-pages-starter", decoder = Decode.succeed () }
)
]
|> ProgramTest.simulateHttpOk
@ -100,7 +100,7 @@ all =
, test "an error is sent out for decoder failures" <|
\() ->
start
[ ( [ "elm-pages" ], { url = "https://api.github.com/repos/dillonkearns/elm-pages", decoder = Decode.fail "The user should get this message from the CLI." } )
[ ( [ "elm-pages" ], { url = \_ -> Ok "https://api.github.com/repos/dillonkearns/elm-pages", decoder = Decode.fail "The user should get this message from the CLI." } )
]
|> ProgramTest.simulateHttpOk
"GET"
@ -119,10 +119,49 @@ all =
)
]
)
, test "uses real secrets to perform request and masked secrets to store and lookup response" <|
\() ->
start
[ ( []
, { url =
\secrets ->
secrets
|> Secrets.get "API_KEY"
|> Result.map
(\apiKey ->
"https://api.github.com/repos/dillonkearns/elm-pages?apiKey=" ++ apiKey
)
, decoder = Decode.succeed ()
}
)
]
|> ProgramTest.simulateHttpOk
"GET"
"https://api.github.com/repos/dillonkearns/elm-pages?apiKey=ABCD1234"
"""{ "stargazer_count": 86 }"""
|> ProgramTest.expectOutgoingPortValues
"toJsPort"
(Codec.decoder Main.toJsCodec)
(Expect.equal
[ Main.Success
{ pages =
Dict.fromList
[ ( "/"
, Dict.fromList
[ ( "https://api.github.com/repos/dillonkearns/elm-pages?apiKey=<API_KEY>"
, """{ "stargazer_count": 86 }"""
)
]
)
]
, manifest = manifest
}
]
)
]
start : List ( List String, { url : String, decoder : Decode.Decoder () } ) -> ProgramTest Main.Model Main.Msg (Main.Effect PathKey)
start : List ( List String, { url : Secrets -> Result String String, decoder : Decode.Decoder () } ) -> ProgramTest Main.Model Main.Msg (Main.Effect PathKey)
start pages =
let
document =
@ -174,7 +213,7 @@ start pages =
in
case thing of
Just { url, decoder } ->
StaticHttp.jsonRequest url
StaticHttp.jsonRequestWithSecrets url
decoder
|> StaticHttp.map
(\staticData -> { view = \model viewForPage -> { title = "Title", body = Html.text "" }, head = [] })
@ -189,7 +228,19 @@ start pages =
, view = \_ -> { title = "", body = [ Html.text "" ] }
}
|> ProgramTest.withSimulatedEffects simulateEffects
|> ProgramTest.start ()
|> ProgramTest.start (flags """{"secrets":
{"API_KEY": "ABCD1234"}
}""")
flags : String -> Decode.Value
flags jsonString =
case Decode.decodeString Decode.value jsonString of
Ok value ->
value
Err _ ->
Debug.todo "Invalid JSON value."
simulateEffects : Main.Effect PathKey -> ProgramTest.SimulatedEffect Main.Msg
@ -207,12 +258,7 @@ simulateEffects effect =
|> List.map simulateEffects
|> SimulatedEffect.Cmd.batch
FetchHttp urlWithSecrets ->
let
realSecrets =
-- TODO @@@@@
Secrets.empty
in
FetchHttp realSecrets urlWithSecrets ->
SimulatedEffect.Http.get
{ url = urlWithSecrets realSecrets |> Result.withDefault "TODO" -- TODO handle error
, expect =