bloodhound-1.0.0.0: tests/Test/SecurityServiceAccountsSpec.hs
{-# LANGUAGE OverloadedStrings #-}
module Test.SecurityServiceAccountsSpec (spec) where
import Data.Aeson
import Data.Aeson.KeyMap qualified as KM
import Data.ByteString.Lazy.Char8 qualified as L
import Data.List (lookup)
import TestsUtils.Import
import Prelude
-- | @GET /_security/service/elastic/fleet-server@ response, keyed by the
-- full principal (documented 7.17 example, trimmed). The
-- @role_descriptor@ is structurally a 'Role'.
sampleServiceAccountBytes :: L.ByteString
sampleServiceAccountBytes =
"{\
\ \"elastic/fleet-server\": {\
\ \"role_descriptor\": {\
\ \"cluster\": [\"monitor\", \"manage_own_api_key\"],\
\ \"indices\": [\
\ {\
\ \"names\": [\"logs-*\"],\
\ \"privileges\": [\"write\", \"create_index\"]\
\ }\
\ ],\
\ \"applications\": [],\
\ \"run_as\": [],\
\ \"metadata\": {},\
\ \"transient_metadata\": {\"enabled\": true}\
\ }\
\ }\
\}"
-- | @POST .../credential/token/token1@ success response carrying the
-- one-time secret bearer value.
sampleCreateServiceTokenBytes :: L.ByteString
sampleCreateServiceTokenBytes =
"{\
\ \"created\": true,\
\ \"token\": {\
\ \"name\": \"token1\",\
\ \"value\": \"AAEAAWVsYXN0aWM...vZmxlZXQtc2VydmVyL3Rva2VuMTo3TFdaSDZ\"\
\ }\
\}"
-- | @GET .../credential@ response listing index-backed tokens and
-- file-backed node credentials (documented 7.17 example).
sampleServiceCredentialsBytes :: L.ByteString
sampleServiceCredentialsBytes =
"{\
\ \"service_account\": \"elastic/fleet-server\",\
\ \"count\": 3,\
\ \"tokens\": {\
\ \"token1\": {},\
\ \"token42\": {}\
\ },\
\ \"nodes_credentials\": {\
\ \"_nodes\": {\"total\": 3, \"successful\": 3, \"failed\": 0},\
\ \"file_tokens\": {\"my-token\": {\"nodes\": [\"node0\", \"node1\"]}}\
\ }\
\}"
-- | @DELETE .../credential/token/{token_name}@ success response.
sampleDeleteServiceTokenBytes :: L.ByteString
sampleDeleteServiceTokenBytes = "{\"found\": true}"
spec :: Spec
spec = describe "Security service accounts" $ do
describe "ServiceAccountsListResponse" $ do
it "decodes a service account keyed by principal" $ do
let Just decoded = decode sampleServiceAccountBytes :: Maybe ServiceAccountsListResponse
Just account = lookup "elastic/fleet-server" (serviceAccountsListEntries decoded)
Just roleDescriptor = saRoleDescriptor account
rCluster roleDescriptor `shouldBe` ["monitor", "manage_own_api_key"]
length (rIndices roleDescriptor) `shouldBe` 1
rTransientMetadata roleDescriptor `shouldSatisfy` isJust
it "round-trips through encode . decode" $ do
let Just decoded = decode sampleServiceAccountBytes :: Maybe ServiceAccountsListResponse
Just roundTripped = decode (encode decoded) :: Maybe ServiceAccountsListResponse
Just account = lookup "elastic/fleet-server" (serviceAccountsListEntries roundTripped)
Just roleDescriptor = saRoleDescriptor account
rCluster roleDescriptor `shouldBe` ["monitor", "manage_own_api_key"]
it "decodes an empty object to no entries" $ do
let Just decoded = decode "{}" :: Maybe ServiceAccountsListResponse
serviceAccountsListEntries decoded `shouldBe` []
describe "CreateServiceTokenResponse" $ do
it "decodes the created flag and the secret token" $ do
let Just decoded = decode sampleCreateServiceTokenBytes :: Maybe CreateServiceTokenResponse
cstrCreated decoded `shouldBe` Just True
let Just secret = cstrToken decoded
stsName secret `shouldBe` Just "token1"
stsValue secret `shouldSatisfy` isJust
it "round-trips through encode . decode" $ do
let Just decoded = decode sampleCreateServiceTokenBytes :: Maybe CreateServiceTokenResponse
Just roundTripped = decode (encode decoded) :: Maybe CreateServiceTokenResponse
Just secret = cstrToken roundTripped
stsName secret `shouldBe` Just "token1"
cstrCreated roundTripped `shouldBe` Just True
describe "GetServiceCredentialsResponse" $ do
it "decodes the tokens map and node credentials" $ do
let Just decoded = decode sampleServiceCredentialsBytes :: Maybe GetServiceCredentialsResponse
gscrServiceAccount decoded `shouldBe` Just "elastic/fleet-server"
gscrCount decoded `shouldBe` Just 3
let Just tokens = gscrTokens decoded
KM.size tokens `shouldBe` 2
gscrNodesCredentials decoded `shouldSatisfy` isJust
it "round-trips through encode . decode" $ do
let Just decoded = decode sampleServiceCredentialsBytes :: Maybe GetServiceCredentialsResponse
Just roundTripped = decode (encode decoded) :: Maybe GetServiceCredentialsResponse
gscrCount roundTripped `shouldBe` Just 3
gscrServiceAccount roundTripped `shouldBe` Just "elastic/fleet-server"
describe "ServiceTokenDeletedResponse" $ do
it "decodes the found flag" $ do
let Just decoded = decode sampleDeleteServiceTokenBytes :: Maybe ServiceTokenDeletedResponse
stdFound decoded `shouldBe` Just True
stdExtras decoded `shouldBe` KM.empty