diff --git a/src/barabadb/core/httpserver.nim b/src/barabadb/core/httpserver.nim index a51823e..5c57526 100644 --- a/src/barabadb/core/httpserver.nim +++ b/src/barabadb/core/httpserver.nim @@ -42,11 +42,11 @@ proc newHttpServer*(config: BaraConfig): HttpServer = let db = newLSMTree(dataDir) let ctx = newExecutionContext(db) ctx.txnManager = newTxnManager() - let ws = newWsServer() + let secret = if config.jwtSecret.len > 0: config.jwtSecret else: "baradb-default-secret-change-in-production!" + let ws = newWsServer(config, secret) ctx.onChange = proc(ev: ChangeEvent) = let msg = $ev.kind & " " & ev.table asyncCheck ws.broadcastToTable(ev.table, msg) - let secret = if config.jwtSecret.len > 0: config.jwtSecret else: "baradb-default-secret-change-in-production!" HttpServer(config: config, running: false, db: db, ctx: ctx, secretKey: secret, metrics: Metrics(), ws: ws) diff --git a/src/barabadb/core/websocket.nim b/src/barabadb/core/websocket.nim index d0d99df..36a6b3d 100644 --- a/src/barabadb/core/websocket.nim +++ b/src/barabadb/core/websocket.nim @@ -5,6 +5,8 @@ import std/strutils import std/tables import std/base64 import std/sets +import config +import jwt as jwtlib type WsFrame = object @@ -24,11 +26,14 @@ type clients*: Table[int, WsClient] nextId: int running: bool + config*: BaraConfig + secretKey*: string onInsert*: proc (table, key, value: string) {.closure.} onDelete*: proc (table, key: string) {.closure.} -proc newWsServer*(): WsServer = - WsServer(clients: initTable[int, WsClient](), nextId: 1, running: false) +proc newWsServer*(cfg: BaraConfig = defaultConfig(), secret: string = ""): WsServer = + WsServer(clients: initTable[int, WsClient](), nextId: 1, running: false, + config: cfg, secretKey: secret) # ---------------------------------------------------------------------- # WebSocket frame encoding/decoding (RFC 6455) @@ -270,6 +275,25 @@ proc handleConnection(server: WsServer, client: AsyncSocket) {.async.} = client.close() return + # Auth check + if server.config.authEnabled: + let authHeader = headers.getOrDefault("authorization", "") + if authHeader.len == 0 or not authHeader.startsWith("Bearer "): + await client.send("HTTP/1.1 401 Unauthorized\r\n\r\n") + client.close() + return + let tokenStr = authHeader[7..^1] + try: + let token = tokenStr.toJWT() + if not token.verify(server.secretKey, HS256): + await client.send("HTTP/1.1 401 Unauthorized\r\n\r\n") + client.close() + return + except: + await client.send("HTTP/1.1 401 Unauthorized\r\n\r\n") + client.close() + return + let acceptKey = computeAcceptKey(wsKey) var response = "HTTP/1.1 101 Switching Protocols\r\n"