2024-01-03 13:06:53 +00:00
|
|
|
# json-rpc
|
|
|
|
# Copyright (c) 2019-2023 Status Research & Development GmbH
|
|
|
|
# Licensed under either of
|
|
|
|
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
|
|
|
|
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
|
|
|
|
# at your option.
|
|
|
|
# This file may not be copied, modified, or distributed except according to
|
|
|
|
# those terms.
|
|
|
|
|
2022-07-17 05:41:18 +00:00
|
|
|
import
|
2022-12-02 12:17:27 +00:00
|
|
|
unittest2,
|
2022-07-17 05:41:18 +00:00
|
|
|
websock/websock,
|
2022-11-08 13:39:29 +00:00
|
|
|
../json_rpc/[rpcclient, rpcserver]
|
2022-07-17 05:41:18 +00:00
|
|
|
|
|
|
|
const
|
2024-01-03 13:06:53 +00:00
|
|
|
serverHost = "127.0.0.1"
|
2024-01-07 07:40:59 +00:00
|
|
|
serverPort = 0 # let the OS choose the port
|
2022-07-17 05:41:18 +00:00
|
|
|
serverAddress = serverHost & ":" & $serverPort
|
|
|
|
|
|
|
|
proc setupServer*(srv: RpcServer) =
|
|
|
|
srv.rpc("testHook") do(input: string):
|
|
|
|
return %("Hello " & input)
|
|
|
|
|
|
|
|
proc authHeaders(): seq[(string, string)] =
|
|
|
|
@[("Auth-Token", "Good Token")]
|
|
|
|
|
|
|
|
suite "HTTP server hook test":
|
2024-01-27 11:00:02 +00:00
|
|
|
proc mockAuth(req: HttpRequestRef): Future[HttpResponseRef] {.
|
|
|
|
gcsafe, async: (raises: [CatchableError]).} =
|
2022-07-17 05:41:18 +00:00
|
|
|
if req.headers.getString("Auth-Token") == "Good Token":
|
|
|
|
return HttpResponseRef(nil)
|
|
|
|
|
|
|
|
return await req.respond(Http401, "Unauthorized access")
|
|
|
|
|
|
|
|
let srv = newRpcHttpServer([serverAddress], @[HttpAuthHook(mockAuth)])
|
|
|
|
srv.setupServer()
|
|
|
|
srv.start()
|
|
|
|
|
|
|
|
test "no auth token":
|
|
|
|
let client = newRpcHttpClient()
|
2024-01-07 07:40:59 +00:00
|
|
|
waitFor client.connect("http://" & $srv.localAddress()[0])
|
2022-07-17 05:41:18 +00:00
|
|
|
expect ErrorResponse:
|
|
|
|
let r = waitFor client.call("testHook", %[%"abc"])
|
2024-01-03 13:06:53 +00:00
|
|
|
discard r
|
2022-07-17 05:41:18 +00:00
|
|
|
|
|
|
|
test "good auth token":
|
|
|
|
let client = newRpcHttpClient(getHeaders = authHeaders)
|
2024-01-07 07:40:59 +00:00
|
|
|
waitFor client.connect("http://" & $srv.localAddress()[0])
|
2022-07-17 05:41:18 +00:00
|
|
|
let r = waitFor client.call("testHook", %[%"abc"])
|
2024-01-03 13:06:53 +00:00
|
|
|
check r.string == "\"Hello abc\""
|
2022-07-17 05:41:18 +00:00
|
|
|
|
|
|
|
waitFor srv.closeWait()
|
|
|
|
|
|
|
|
proc wsAuthHeaders(ctx: Hook,
|
|
|
|
headers: var HttpTable): Result[void, string]
|
2024-01-03 13:06:53 +00:00
|
|
|
{.gcsafe, raises: [].} =
|
2022-07-17 05:41:18 +00:00
|
|
|
headers.add("Auth-Token", "Good Token")
|
|
|
|
return ok()
|
|
|
|
|
|
|
|
suite "Websocket server hook test":
|
|
|
|
let hook = Hook(append: wsAuthHeaders)
|
|
|
|
|
|
|
|
proc mockAuth(req: websock.HttpRequest): Future[bool] {.async.} =
|
|
|
|
if not req.headers.contains("Auth-Token"):
|
|
|
|
await req.sendResponse(code = Http403, data = "Missing Auth-Token")
|
|
|
|
return false
|
|
|
|
|
|
|
|
let token = req.headers.getString("Auth-Token")
|
|
|
|
if token != "Good Token":
|
|
|
|
await req.sendResponse(code = Http401, data = "Unauthorized access")
|
|
|
|
return false
|
|
|
|
|
|
|
|
return true
|
|
|
|
|
|
|
|
let srv = newRpcWebSocketServer(
|
2024-01-07 07:40:59 +00:00
|
|
|
serverHost,
|
|
|
|
Port(serverPort),
|
2022-07-17 05:41:18 +00:00
|
|
|
authHooks = @[WsAuthHook(mockAuth)]
|
|
|
|
)
|
|
|
|
srv.setupServer()
|
|
|
|
srv.start()
|
|
|
|
let client = newRpcWebSocketClient()
|
|
|
|
|
|
|
|
test "no auth token":
|
|
|
|
try:
|
2024-01-07 07:40:59 +00:00
|
|
|
waitFor client.connect("ws://" & $srv.localAddress())
|
2022-07-17 05:41:18 +00:00
|
|
|
check false
|
|
|
|
except CatchableError as e:
|
2024-01-07 07:40:59 +00:00
|
|
|
check e.msg == "Server did not reply with a websocket upgrade: Header code: 403 Header reason: Forbidden Address: " & $srv.localAddress()
|
2022-07-17 05:41:18 +00:00
|
|
|
|
|
|
|
test "good auth token":
|
2024-01-07 07:40:59 +00:00
|
|
|
waitFor client.connect("ws://" & $srv.localAddress(), hooks = @[hook])
|
2022-07-17 05:41:18 +00:00
|
|
|
let r = waitFor client.call("testHook", %[%"abc"])
|
2024-01-03 13:06:53 +00:00
|
|
|
check r.string == "\"Hello abc\""
|
2022-07-17 05:41:18 +00:00
|
|
|
|
|
|
|
srv.stop()
|
|
|
|
waitFor srv.closeWait()
|