nimbus-eth1/hive_integration/nodocker/engine/auths_tests.nim

110 lines
3.4 KiB
Nim

import
std/[base64, times, strutils],
test_env,
unittest2,
chronicles,
nimcrypto/[hmac, utils],
json_rpc/[rpcclient],
./types
# JWT Authentication Related
const
defaultJwtTokenSecretBytes = "secretsecretsecretsecretsecretse"
maxTimeDriftSeconds = 5'i64
defaultProtectedHeader = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9"
proc base64urlEncode(x: auto): string =
base64.encode(x, safe = true).replace("=", "")
proc prepareAuthCallToken(secret: string, time: int64): string =
let key = cast[seq[byte]](secret)
let payload = """{"iat": $1}""" % [$time]
let token = defaultProtectedHeader & "." & payload.base64urlEncode
let sig = base64urlEncode(sha256.hmac(key, token).data)
token & "." & sig
proc getClient(t: TestEnv, token: string): RpcHttpClient =
proc authHeaders(): seq[(string, string)] =
@[("Authorization", "Bearer " & token)]
let client = newRpcHttpClient(getHeaders = authHeaders)
waitFor client.connect("localhost", t.conf.rpcPort, false)
return client
template genAuthTest(procName: untyped, timeDriftSeconds: int64, customAuthSecretBytes: string, authOK: bool) =
proc procName(t: TestEnv): TestStatus =
result = TestStatus.OK
# Default values
var
# All test cases send a simple TransitionConfigurationV1 to check the Authentication mechanism (JWT)
tConf = TransitionConfigurationV1(
terminalTotalDifficulty: t.ttd
)
testSecret = customAuthSecretBytes
testTime = getTime().toUnix
if testSecret.len == 0:
testSecret = defaultJwtTokenSecretBytes
if timeDriftSeconds != 0:
testTime = testTime + timeDriftSeconds
let token = prepareAuthCallToken(testSecret, testTime)
let client = getClient(t, token)
try:
discard waitFor client.call("engine_exchangeTransitionConfigurationV1", %[%tConf])
testCond authOk:
error "Authentication was supposed to fail authentication but passed"
except CatchableError:
testCond not authOk:
error "Authentication was supposed to pass authentication but failed"
genAuthTest(authTest1, 0'i64, "", true)
genAuthTest(authTest2, 0'i64, "secretsecretsecretsecretsecrets", false)
genAuthTest(authTest3, 0'i64, "\0secretsecretsecretsecretsecretse", false)
genAuthTest(authTest4, -1 - maxTimeDriftSeconds, "", false)
genAuthTest(authTest5, 1 - maxTimeDriftSeconds, "", true)
genAuthTest(authTest6, maxTimeDriftSeconds + 1, "", false)
genAuthTest(authTest7, maxTimeDriftSeconds - 1, "", true)
# JWT Authentication Tests
const authTestList* = [
TestSpec(
name: "JWT Authentication: No time drift, correct secret",
run: authTest1,
enableAuth: true
),
TestSpec(
name: "JWT Authentication: No time drift, incorrect secret (shorter)",
run: authTest2,
enableAuth: true
),
TestSpec(
name: "JWT Authentication: No time drift, incorrect secret (longer)",
run: authTest3,
enableAuth: true
),
TestSpec(
name: "JWT Authentication: Negative time drift, exceeding limit, correct secret",
run: authTest4,
enableAuth: true
),
TestSpec(
name: "JWT Authentication: Negative time drift, within limit, correct secret",
run: authTest5,
enableAuth: true
),
TestSpec(
name: "JWT Authentication: Positive time drift, exceeding limit, correct secret",
run: authTest6,
enableAuth: true
),
TestSpec(
name: "JWT Authentication: Positive time drift, within limit, correct secret",
run: authTest7,
enableAuth: true
)
]