feat(users/Profpatsch/whatcd-resolver): read redacted key from env
Change-Id: I5667710423aeeacfbb8dddf5b0b8750dc8f878aa Reviewed-on: https://cl.tvl.fyi/c/depot/+/12055 Tested-by: BuildkiteCI Reviewed-by: Profpatsch <mail@profpatsch.de>
This commit is contained in:
parent
1f65a7b0d0
commit
a86dca8c78
3 changed files with 44 additions and 17 deletions
|
@ -12,6 +12,8 @@ import Data.Pool (Pool)
|
||||||
import Data.Text qualified as Text
|
import Data.Text qualified as Text
|
||||||
import Database.PostgreSQL.Simple qualified as Postgres
|
import Database.PostgreSQL.Simple qualified as Postgres
|
||||||
import GHC.Stack qualified
|
import GHC.Stack qualified
|
||||||
|
import Json.Enc
|
||||||
|
import Json.Enc qualified as Enc
|
||||||
import Label
|
import Label
|
||||||
import OpenTelemetry.Trace qualified as Otel hiding (getTracer, inSpan, inSpan')
|
import OpenTelemetry.Trace qualified as Otel hiding (getTracer, inSpan, inSpan')
|
||||||
import OpenTelemetry.Trace.Core qualified as Otel hiding (inSpan, inSpan')
|
import OpenTelemetry.Trace.Core qualified as Otel hiding (inSpan, inSpan')
|
||||||
|
@ -27,7 +29,8 @@ data Context = Context
|
||||||
tracer :: Otel.Tracer,
|
tracer :: Otel.Tracer,
|
||||||
pgFormat :: PgFormatPool,
|
pgFormat :: PgFormatPool,
|
||||||
pgConnPool :: Pool Postgres.Connection,
|
pgConnPool :: Pool Postgres.Connection,
|
||||||
transmissionSessionId :: IORef (Maybe ByteString)
|
transmissionSessionId :: IORef (Maybe ByteString),
|
||||||
|
redactedApiKey :: ByteString
|
||||||
}
|
}
|
||||||
|
|
||||||
newtype AppT m a = AppT {unAppT :: ReaderT Context m a}
|
newtype AppT m a = AppT {unAppT :: ReaderT Context m a}
|
||||||
|
@ -67,6 +70,15 @@ addAttribute span key a = Otel.addAttribute span ("_." <> key) a
|
||||||
addAttributes :: (MonadIO m) => Otel.Span -> HashMap Text Otel.Attribute -> m ()
|
addAttributes :: (MonadIO m) => Otel.Span -> HashMap Text Otel.Attribute -> m ()
|
||||||
addAttributes span attrs = Otel.addAttributes span $ attrs & HashMap.mapKeys ("_." <>)
|
addAttributes span attrs = Otel.addAttributes span $ attrs & HashMap.mapKeys ("_." <>)
|
||||||
|
|
||||||
|
-- | Create an otel attribute from a json encoder
|
||||||
|
jsonAttribute :: Enc -> Otel.Attribute
|
||||||
|
jsonAttribute e = e & Enc.encToTextPretty & Otel.toAttribute
|
||||||
|
|
||||||
|
orThrowAppErrorNewSpan :: (MonadThrow m, MonadOtel m) => Text -> Either ErrorTree a -> m a
|
||||||
|
orThrowAppErrorNewSpan msg = \case
|
||||||
|
Left err -> appThrowTreeNewSpan msg err
|
||||||
|
Right a -> pure a
|
||||||
|
|
||||||
appThrowTreeNewSpan :: (MonadThrow m, MonadOtel m) => Text -> ErrorTree -> m a
|
appThrowTreeNewSpan :: (MonadThrow m, MonadOtel m) => Text -> ErrorTree -> m a
|
||||||
appThrowTreeNewSpan spanName exc = inSpan' spanName $ \span -> do
|
appThrowTreeNewSpan spanName exc = inSpan' spanName $ \span -> do
|
||||||
let msg = prettyErrorTree exc
|
let msg = prettyErrorTree exc
|
||||||
|
@ -127,7 +139,7 @@ recordException span dat = liftIO $ do
|
||||||
HashMap.fromList
|
HashMap.fromList
|
||||||
[ ("exception.type", Otel.toAttribute @Text dat.type_),
|
[ ("exception.type", Otel.toAttribute @Text dat.type_),
|
||||||
("exception.message", Otel.toAttribute @Text dat.message),
|
("exception.message", Otel.toAttribute @Text dat.message),
|
||||||
("exception.stacktrace", Otel.toAttribute @Text $ Text.unlines $ map stringToText callStack)
|
("exception.stacktrace", Otel.toAttribute @Text $ Text.unlines $ Prelude.map stringToText callStack)
|
||||||
],
|
],
|
||||||
..
|
..
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,11 +27,16 @@ import Optional
|
||||||
import Postgres.Decoder qualified as Dec
|
import Postgres.Decoder qualified as Dec
|
||||||
import Postgres.MonadPostgres
|
import Postgres.MonadPostgres
|
||||||
import Pretty
|
import Pretty
|
||||||
import RunCommand (runCommandExpect0)
|
|
||||||
import Prelude hiding (span)
|
import Prelude hiding (span)
|
||||||
|
|
||||||
|
class MonadRedacted m where
|
||||||
|
getRedactedApiKey :: m ByteString
|
||||||
|
|
||||||
|
instance (MonadIO m) => MonadRedacted (AppT m) where
|
||||||
|
getRedactedApiKey = AppT (asks (.redactedApiKey))
|
||||||
|
|
||||||
redactedSearch ::
|
redactedSearch ::
|
||||||
(MonadLogger m, MonadThrow m, MonadOtel m) =>
|
(MonadThrow m, MonadOtel m, MonadRedacted m) =>
|
||||||
[(ByteString, ByteString)] ->
|
[(ByteString, ByteString)] ->
|
||||||
Json.Parse ErrorTree a ->
|
Json.Parse ErrorTree a ->
|
||||||
m a
|
m a
|
||||||
|
@ -48,7 +53,8 @@ redactedGetTorrentFile ::
|
||||||
( MonadLogger m,
|
( MonadLogger m,
|
||||||
MonadThrow m,
|
MonadThrow m,
|
||||||
HasField "torrentId" dat Int,
|
HasField "torrentId" dat Int,
|
||||||
MonadOtel m
|
MonadOtel m,
|
||||||
|
MonadRedacted m
|
||||||
) =>
|
) =>
|
||||||
dat ->
|
dat ->
|
||||||
m ByteString
|
m ByteString
|
||||||
|
@ -71,7 +77,7 @@ redactedGetTorrentFile dat = inSpan' "Redacted Get Torrent File" $ \span -> do
|
||||||
mkRedactedTorrentLink :: Arg "torrentGroupId" Int -> Text
|
mkRedactedTorrentLink :: Arg "torrentGroupId" Int -> Text
|
||||||
mkRedactedTorrentLink torrentId = [fmt|https://redacted.ch/torrents.php?id={torrentId.unArg}|]
|
mkRedactedTorrentLink torrentId = [fmt|https://redacted.ch/torrents.php?id={torrentId.unArg}|]
|
||||||
|
|
||||||
exampleSearch :: (MonadThrow m, MonadLogger m, MonadPostgres m, MonadOtel m) => m (Transaction m ())
|
exampleSearch :: (MonadThrow m, MonadLogger m, MonadPostgres m, MonadOtel m, MonadRedacted m) => m (Transaction m ())
|
||||||
exampleSearch = do
|
exampleSearch = do
|
||||||
t1 <-
|
t1 <-
|
||||||
redactedSearchAndInsert
|
redactedSearchAndInsert
|
||||||
|
@ -108,7 +114,8 @@ redactedSearchAndInsert ::
|
||||||
( MonadLogger m,
|
( MonadLogger m,
|
||||||
MonadPostgres m,
|
MonadPostgres m,
|
||||||
MonadThrow m,
|
MonadThrow m,
|
||||||
MonadOtel m
|
MonadOtel m,
|
||||||
|
MonadRedacted m
|
||||||
) =>
|
) =>
|
||||||
[(ByteString, ByteString)] ->
|
[(ByteString, ByteString)] ->
|
||||||
m (Transaction m ())
|
m (Transaction m ())
|
||||||
|
@ -289,12 +296,13 @@ redactedGetTorrentFileAndInsert ::
|
||||||
MonadPostgres m,
|
MonadPostgres m,
|
||||||
MonadThrow m,
|
MonadThrow m,
|
||||||
MonadLogger m,
|
MonadLogger m,
|
||||||
MonadOtel m
|
MonadOtel m,
|
||||||
|
MonadRedacted m
|
||||||
) =>
|
) =>
|
||||||
r ->
|
r ->
|
||||||
Transaction m (Label "torrentFile" ByteString)
|
Transaction m (Label "torrentFile" ByteString)
|
||||||
redactedGetTorrentFileAndInsert dat = inSpan' "Redacted Get Torrent File and Insert" $ \span -> do
|
redactedGetTorrentFileAndInsert dat = inSpan' "Redacted Get Torrent File and Insert" $ \span -> do
|
||||||
bytes <- redactedGetTorrentFile dat
|
bytes <- lift $ redactedGetTorrentFile dat
|
||||||
execute
|
execute
|
||||||
[sql|
|
[sql|
|
||||||
UPDATE redacted.torrents_json
|
UPDATE redacted.torrents_json
|
||||||
|
@ -468,15 +476,14 @@ getBestTorrents opts = do
|
||||||
-- | Do a request to the redacted API. If you know what that is, you know how to find the API docs.
|
-- | Do a request to the redacted API. If you know what that is, you know how to find the API docs.
|
||||||
mkRedactedApiRequest ::
|
mkRedactedApiRequest ::
|
||||||
( MonadThrow m,
|
( MonadThrow m,
|
||||||
MonadIO m,
|
|
||||||
MonadLogger m,
|
|
||||||
HasField "action" p ByteString,
|
HasField "action" p ByteString,
|
||||||
HasField "actionArgs" p [(ByteString, Maybe ByteString)]
|
HasField "actionArgs" p [(ByteString, Maybe ByteString)],
|
||||||
|
MonadRedacted m
|
||||||
) =>
|
) =>
|
||||||
p ->
|
p ->
|
||||||
m Http.Request
|
m Http.Request
|
||||||
mkRedactedApiRequest dat = do
|
mkRedactedApiRequest dat = do
|
||||||
authKey <- runCommandExpect0 "pass" ["internet/redacted/api-keys/whatcd-resolver"]
|
authKey <- getRedactedApiKey
|
||||||
pure $
|
pure $
|
||||||
[fmt|https://redacted.ch/ajax.php|]
|
[fmt|https://redacted.ch/ajax.php|]
|
||||||
& Http.setRequestMethod "GET"
|
& Http.setRequestMethod "GET"
|
||||||
|
@ -558,10 +565,10 @@ httpJson opts parser req = inSpan' "HTTP Request (JSON)" $ \span -> do
|
||||||
|
|
||||||
redactedApiRequestJson ::
|
redactedApiRequestJson ::
|
||||||
( MonadThrow m,
|
( MonadThrow m,
|
||||||
MonadLogger m,
|
|
||||||
HasField "action" p ByteString,
|
HasField "action" p ByteString,
|
||||||
HasField "actionArgs" p [(ByteString, Maybe ByteString)],
|
HasField "actionArgs" p [(ByteString, Maybe ByteString)],
|
||||||
MonadOtel m
|
MonadOtel m,
|
||||||
|
MonadRedacted m
|
||||||
) =>
|
) =>
|
||||||
p ->
|
p ->
|
||||||
Json.Parse ErrorTree a ->
|
Json.Parse ErrorTree a ->
|
||||||
|
|
|
@ -11,7 +11,7 @@ import Control.Monad.Reader
|
||||||
import Data.Aeson qualified as Json
|
import Data.Aeson qualified as Json
|
||||||
import Data.Aeson.BetterErrors qualified as Json
|
import Data.Aeson.BetterErrors qualified as Json
|
||||||
import Data.Aeson.KeyMap qualified as KeyMap
|
import Data.Aeson.KeyMap qualified as KeyMap
|
||||||
import Data.Error.Tree (prettyErrorTree)
|
import Data.Error.Tree
|
||||||
import Data.HashMap.Strict qualified as HashMap
|
import Data.HashMap.Strict qualified as HashMap
|
||||||
import Data.List qualified as List
|
import Data.List qualified as List
|
||||||
import Data.Map.Strict qualified as Map
|
import Data.Map.Strict qualified as Map
|
||||||
|
@ -52,6 +52,7 @@ import Postgres.Decoder qualified as Dec
|
||||||
import Postgres.MonadPostgres
|
import Postgres.MonadPostgres
|
||||||
import Pretty
|
import Pretty
|
||||||
import Redacted
|
import Redacted
|
||||||
|
import RunCommand (runCommandExpect0)
|
||||||
import System.Directory qualified as Dir
|
import System.Directory qualified as Dir
|
||||||
import System.Directory qualified as Xdg
|
import System.Directory qualified as Xdg
|
||||||
import System.Environment qualified as Env
|
import System.Environment qualified as Env
|
||||||
|
@ -469,7 +470,8 @@ snipsRedactedSearch ::
|
||||||
HasField "searchstr" r ByteString,
|
HasField "searchstr" r ByteString,
|
||||||
MonadThrow m,
|
MonadThrow m,
|
||||||
MonadTransmission m,
|
MonadTransmission m,
|
||||||
MonadOtel m
|
MonadOtel m,
|
||||||
|
MonadRedacted m
|
||||||
) =>
|
) =>
|
||||||
r ->
|
r ->
|
||||||
m Html
|
m Html
|
||||||
|
@ -758,6 +760,12 @@ runAppWith appT = withTracer $ \tracer -> withDb $ \db -> do
|
||||||
{- unusedResourceOpenTime -} 10
|
{- unusedResourceOpenTime -} 10
|
||||||
{- max resources across all stripes -} 20
|
{- max resources across all stripes -} 20
|
||||||
transmissionSessionId <- newIORef Nothing
|
transmissionSessionId <- newIORef Nothing
|
||||||
|
redactedApiKey <-
|
||||||
|
Env.lookupEnv "WHATCD_RESOLVER_REDACTED_API_KEY" >>= \case
|
||||||
|
Just k -> pure (k & stringToBytesUtf8)
|
||||||
|
Nothing -> runStderrLoggingT $ do
|
||||||
|
logInfo "WHATCD_RESOLVER_REDACTED_API_KEY was not set, trying pass"
|
||||||
|
runCommandExpect0 "pass" ["internet/redacted/api-keys/whatcd-resolver"]
|
||||||
let newAppT = do
|
let newAppT = do
|
||||||
logInfo [fmt|Running with config: {showPretty config}|]
|
logInfo [fmt|Running with config: {showPretty config}|]
|
||||||
logInfo [fmt|Connected to database at {db & TmpPg.toDataDirectory} on socket {db & TmpPg.toConnectionString}|]
|
logInfo [fmt|Connected to database at {db & TmpPg.toDataDirectory} on socket {db & TmpPg.toConnectionString}|]
|
||||||
|
|
Loading…
Reference in a new issue