2026-07-19 23:57:21 +09:00
|
|
|
module Nuthatch.Probe.ProductClient
|
|
|
|
|
( browse
|
|
|
|
|
, deleteObject
|
|
|
|
|
, download
|
|
|
|
|
, sha256Hex
|
|
|
|
|
, upload
|
|
|
|
|
) where
|
|
|
|
|
|
|
|
|
|
import Crypto.Hash (Digest, SHA256, hash)
|
|
|
|
|
import qualified Data.ByteArray as BA
|
|
|
|
|
import qualified Data.ByteString as BS
|
|
|
|
|
import qualified Data.ByteString.Base16 as B16
|
|
|
|
|
import qualified Data.ByteString.Char8 as B8
|
|
|
|
|
import qualified Data.Text as Text
|
|
|
|
|
import qualified Data.Text.Encoding as Text
|
|
|
|
|
import Network.HTTP.Types.URI (urlEncode)
|
2026-07-20 23:06:01 +09:00
|
|
|
import Nuthatch.Probe.Http
|
2026-07-19 23:57:21 +09:00
|
|
|
import Nuthatch.Probe.Oidc
|
|
|
|
|
|
|
|
|
|
browse
|
|
|
|
|
:: ProbeContext
|
|
|
|
|
-> Session
|
|
|
|
|
-> String
|
2026-07-20 23:06:01 +09:00
|
|
|
-> IO ProbeResponse
|
2026-07-19 23:57:21 +09:00
|
|
|
browse context session query =
|
2026-07-20 23:06:01 +09:00
|
|
|
getWith
|
|
|
|
|
(probeClient context)
|
|
|
|
|
defaultRequestOptions
|
|
|
|
|
{ optionCookies = Just (sessionCookies session)
|
|
|
|
|
, optionHeaders = [("Accept", "application/json")]
|
|
|
|
|
}
|
|
|
|
|
(probeBase context <> "/api/browse" <> query)
|
2026-07-19 23:57:21 +09:00
|
|
|
|
|
|
|
|
download
|
|
|
|
|
:: ProbeContext
|
|
|
|
|
-> Session
|
|
|
|
|
-> String
|
|
|
|
|
-> String
|
2026-07-20 23:06:01 +09:00
|
|
|
-> IO ProbeResponse
|
|
|
|
|
download context session root path =
|
|
|
|
|
getWith
|
|
|
|
|
(probeClient context)
|
|
|
|
|
defaultRequestOptions
|
|
|
|
|
{ optionCookies = Just (sessionCookies session) }
|
|
|
|
|
( probeBase context
|
|
|
|
|
<> "/api/download?root="
|
|
|
|
|
<> encode root
|
|
|
|
|
<> "&path="
|
|
|
|
|
<> encode path
|
2026-07-19 23:57:21 +09:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
upload
|
|
|
|
|
:: ProbeContext
|
|
|
|
|
-> Session
|
|
|
|
|
-> String
|
|
|
|
|
-> String
|
|
|
|
|
-> String
|
|
|
|
|
-> BS.ByteString
|
2026-07-20 23:06:01 +09:00
|
|
|
-> IO ProbeResponse
|
|
|
|
|
upload context session root path operationId body =
|
|
|
|
|
postWith
|
|
|
|
|
(probeClient context)
|
|
|
|
|
defaultRequestOptions
|
|
|
|
|
{ optionCookies = Just (sessionCookies session)
|
|
|
|
|
, optionHeaders =
|
|
|
|
|
[ ("Content-Type", "application/octet-stream")
|
|
|
|
|
, ("X-Declared-Size", B8.pack (show (BS.length body)))
|
|
|
|
|
, ("X-Content-SHA256", sha256Hex body)
|
|
|
|
|
, ("X-CSRF-Token", sessionCsrf session)
|
|
|
|
|
]
|
|
|
|
|
, optionBody = ByteBody body
|
|
|
|
|
}
|
|
|
|
|
( probeBase context
|
|
|
|
|
<> "/api/upload?root="
|
|
|
|
|
<> encode root
|
|
|
|
|
<> "&path="
|
|
|
|
|
<> encode path
|
|
|
|
|
<> "&operation_id="
|
|
|
|
|
<> encode operationId
|
|
|
|
|
)
|
2026-07-19 23:57:21 +09:00
|
|
|
|
|
|
|
|
deleteObject
|
|
|
|
|
:: ProbeContext
|
|
|
|
|
-> Session
|
|
|
|
|
-> String
|
|
|
|
|
-> String
|
|
|
|
|
-> String
|
2026-07-20 23:06:01 +09:00
|
|
|
-> IO ProbeResponse
|
2026-07-19 23:57:21 +09:00
|
|
|
deleteObject context session root path operationId =
|
2026-07-20 23:06:01 +09:00
|
|
|
postWith
|
|
|
|
|
(probeClient context)
|
|
|
|
|
defaultRequestOptions
|
|
|
|
|
{ optionCookies = Just (sessionCookies session)
|
|
|
|
|
, optionHeaders = [("Content-Type", "application/json")]
|
|
|
|
|
, optionBody = ByteBody . B8.pack $
|
|
|
|
|
"{\"root\":\""
|
2026-07-19 23:57:21 +09:00
|
|
|
<> root
|
|
|
|
|
<> "\",\"path\":\""
|
|
|
|
|
<> path
|
|
|
|
|
<> "\",\"operation_id\":\""
|
|
|
|
|
<> operationId
|
|
|
|
|
<> "\",\"csrf\":\""
|
|
|
|
|
<> B8.unpack (sessionCsrf session)
|
|
|
|
|
<> "\"}"
|
2026-07-20 23:06:01 +09:00
|
|
|
}
|
|
|
|
|
(probeBase context <> "/api/delete")
|
2026-07-19 23:57:21 +09:00
|
|
|
|
|
|
|
|
sha256Hex :: BS.ByteString -> BS.ByteString
|
|
|
|
|
sha256Hex input =
|
|
|
|
|
B16.encode (BA.convert (hash input :: Digest SHA256))
|
|
|
|
|
|
|
|
|
|
encode :: String -> String
|
|
|
|
|
encode = B8.unpack . urlEncode True . Text.encodeUtf8 . Text.pack
|