packages feed

salmon-ops-recipes-0.1.0.0: src/SreBox/JWTSigning.hs

{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE OverloadedRecordDot #-}

module SreBox.JWTSigning where

import Data.Aeson (FromJSON, ToJSON)
import Data.Aeson as Aeson
import Data.ByteString (ByteString)
import qualified Data.ByteString as ByteString
import qualified Data.ByteString.Base64 as B64
import qualified Data.ByteString.Base64.URL as B64Url
import qualified Data.ByteString.Lazy as LByteString
import Data.Foldable (for_)
import Data.Text (Text)
import qualified Data.Text as Text
import qualified Data.Text.Encoding as Text
import qualified Jose.Jwa as Jose
import qualified Jose.Jws as Jose

import Salmon.Actions.UpDown (skipIfFileExists)
import Salmon.Builtin.Extension
import qualified Salmon.Builtin.Nodes.Secrets as Secrets
import Salmon.Op.OpGraph (OpGraph (..), inject)
import Salmon.Op.Ref (mkRef)
import Salmon.Op.Track (using)
import Salmon.Reporter

-------------------------------------------------------------------------------
data Report
    = Sign !Secrets.Secret FilePath
    deriving (Show)

signHmac :: Reporter Report -> Tracked' Secrets.Secret -> ByteString -> FilePath -> Op
signHmac r secret jwtPayload jwtPath =
    using secret $ \sekret ->
        op "jwt-signed-token" nodeps $ \actions ->
            actions
                { help = "derive a JWT for claims and and a given signing Key"
                , ref = mkRef "sign-jwt" jwtPath
                , check = skipIfFileExists jwtPath
                , up = up sekret
                }
  where
    up sekret = do
        runReporter r (Sign sekret jwtPath)
        keytxt <- ByteString.readFile sekret.secret_path
        let key = case sekret.secret_type of
                Secrets.Base64 -> B64.decodeLenient keytxt
                Secrets.Base64SafeUrl -> B64Url.decodeLenient keytxt
                Secrets.Hex -> keytxt
        print key
        let jwt = Jose.hmacEncode Jose.HS256 key jwtPayload
        for_ jwt $ \blob ->
            LByteString.writeFile jwtPath (Aeson.encode blob)