Remove dependence on logging framework. Just raise exceptions instead.
This commit is contained in:
parent
feeef6429c
commit
9f302556f6
@ -1,6 +1,6 @@
|
|||||||
# Package
|
# Package
|
||||||
|
|
||||||
version = "0.4.1"
|
version = "0.4.2"
|
||||||
author = "Jonathan Bernard"
|
author = "Jonathan Bernard"
|
||||||
description = "Jonathan's opinionated extensions and auth layer for Jester."
|
description = "Jonathan's opinionated extensions and auth layer for Jester."
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
@ -15,7 +15,7 @@ requires "nim >= 1.6.2"
|
|||||||
requires @["bcrypt", "mummy", "uuids", "webby"]
|
requires @["bcrypt", "mummy", "uuids", "webby"]
|
||||||
|
|
||||||
# from https://git.jdb-software.com/jdb/nim-packages
|
# from https://git.jdb-software.com/jdb/nim-packages
|
||||||
requires @["jwt_full >= 0.2.0", "namespaced_logging >= 0.3.0"]
|
requires @["jwt_full >= 0.2.0"]
|
||||||
|
|
||||||
task unittest, "Runs the unit test suite.":
|
task unittest, "Runs the unit test suite.":
|
||||||
exec "nim c -r test/runner"
|
exec "nim c -r test/runner"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import std/[json, jsonutils, logging, options, sequtils, strtabs, strutils]
|
import std/[json, jsonutils, options, sequtils, strtabs, strutils]
|
||||||
import mummy, namespaced_logging, webby
|
import mummy, webby
|
||||||
|
|
||||||
import std/httpcore except HttpHeaders
|
import std/httpcore except HttpHeaders
|
||||||
|
|
||||||
@ -7,12 +7,6 @@ import ./apierror
|
|||||||
|
|
||||||
const CONTENT_TYPE_JSON* = "application/json"
|
const CONTENT_TYPE_JSON* = "application/json"
|
||||||
|
|
||||||
var logNs {.threadvar.}: LoggingNamespace
|
|
||||||
|
|
||||||
template log(): untyped =
|
|
||||||
if logNs.isNil: logNs = getLoggerForNamespace("buffoonery/apiutils", lvlDebug)
|
|
||||||
logNs
|
|
||||||
|
|
||||||
## Response Utilities
|
## Response Utilities
|
||||||
## ------------------
|
## ------------------
|
||||||
|
|
||||||
@ -65,11 +59,9 @@ proc makeCorsHeaders*(
|
|||||||
}
|
}
|
||||||
else:
|
else:
|
||||||
if reqOrigin.isSome:
|
if reqOrigin.isSome:
|
||||||
log().debug "Unrecognized Origin '" & reqOrigin.get & "', excluding CORS headers."
|
@{"X-Invalid-Origin-Details": "Unrecognized origin '" & reqOrigin.get & "'."}
|
||||||
else:
|
else:
|
||||||
log().debug "No Origin supplied, excluding CORS headers."
|
@{"X-Invalid-Origin-Details": "Missing Origin."}
|
||||||
log().debug "Valid origins: " & allowedOrigins.join(", ")
|
|
||||||
@{:}
|
|
||||||
|
|
||||||
|
|
||||||
proc makeCorsHeaders*(
|
proc makeCorsHeaders*(
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import std/[cookies, json, logging, options, sequtils, strtabs,
|
import std/[cookies, json, options, sequtils, strtabs, strutils, tables, times]
|
||||||
strutils, tables, times]
|
import mummy, uuids, webby
|
||||||
import mummy, namespaced_logging, uuids, webby
|
|
||||||
import std/httpclient except HttpHeaders
|
import std/httpclient except HttpHeaders
|
||||||
|
|
||||||
import jwt_full, jwt_full/encoding
|
import jwt_full, jwt_full/encoding
|
||||||
@ -28,12 +27,6 @@ type
|
|||||||
|
|
||||||
issuerKeys: TableRef[string, JwkSet]
|
issuerKeys: TableRef[string, JwkSet]
|
||||||
|
|
||||||
var logNs {.threadvar.}: LoggingNamespace
|
|
||||||
|
|
||||||
template log(): untyped =
|
|
||||||
if logNs.isNil: logNs = getLoggerForNamespace("buffoonery/auth", lvlDebug)
|
|
||||||
logNs
|
|
||||||
|
|
||||||
|
|
||||||
proc failAuth*(reason: string, parentException: ref Exception = nil) =
|
proc failAuth*(reason: string, parentException: ref Exception = nil) =
|
||||||
## Syntactic sugar to raise an AuthError. Reason will be the exception
|
## Syntactic sugar to raise an AuthError. Reason will be the exception
|
||||||
@ -74,20 +67,17 @@ proc fetchJWKs(openIdConfigUrl: string): JwkSet {.gcsafe.} =
|
|||||||
let http = newHttpClient()
|
let http = newHttpClient()
|
||||||
|
|
||||||
# Inspect the OAuth metadata via the well-known address.
|
# Inspect the OAuth metadata via the well-known address.
|
||||||
log().debug "fetchJwks: Fetching metadata from " & openIdConfigUrl
|
|
||||||
let metadata = parseJson(http.getContent(openIdConfigUrl))
|
let metadata = parseJson(http.getContent(openIdConfigUrl))
|
||||||
|
|
||||||
# Fetch the keys from the jwk_keys URI.
|
# Fetch the keys from the jwk_keys URI.
|
||||||
let jwksKeysURI = metadata.getOrFail("jwks_uri").getStr
|
let jwksKeysURI = metadata.getOrFail("jwks_uri").getStr
|
||||||
debug "fetchJwks: Fetching JWKs from " & jwksKeysURI
|
|
||||||
let jwksKeys = parseJson(http.getContent(jwksKeysURI))
|
let jwksKeys = parseJson(http.getContent(jwksKeysURI))
|
||||||
|
|
||||||
# Parse and load the keys provided.
|
# Parse and load the keys provided.
|
||||||
return initJwkSet(jwksKeys)
|
return initJwkSet(jwksKeys)
|
||||||
|
|
||||||
except:
|
except:
|
||||||
log().error "unable to fetch issuer signing keys: " & getCurrentExceptionMsg()
|
failAuth("unable to fetch isser signing keys", getCurrentException())
|
||||||
failAuth "unable to fetch isser signing keys"
|
|
||||||
|
|
||||||
|
|
||||||
proc addSigningKeys*(ctx: ApiAuthContext, issuer: string, keySet: JwkSet): void =
|
proc addSigningKeys*(ctx: ApiAuthContext, issuer: string, keySet: JwkSet): void =
|
||||||
@ -97,7 +87,6 @@ proc addSigningKeys*(ctx: ApiAuthContext, issuer: string, keySet: JwkSet): void
|
|||||||
if ctx.issuerKeys.isNil: ctx.issuerKeys = newTable[string, JwkSet]()
|
if ctx.issuerKeys.isNil: ctx.issuerKeys = newTable[string, JwkSet]()
|
||||||
ctx.issuerKeys[issuer] = keySet
|
ctx.issuerKeys[issuer] = keySet
|
||||||
except:
|
except:
|
||||||
log().error "unable to add a set of signing keys: " & getCurrentExceptionMsg()
|
|
||||||
raise getCurrentException()
|
raise getCurrentException()
|
||||||
|
|
||||||
|
|
||||||
@ -134,7 +123,6 @@ proc findSigningKey*(ctx: ApiAuthContext, jwt: JWT, allowFetch = true): JWK {.gc
|
|||||||
failAuth "unable to find JWT signing key"
|
failAuth "unable to find JWT signing key"
|
||||||
|
|
||||||
except:
|
except:
|
||||||
log().error "unable to find JWT signing key: " & getCurrentExceptionMsg()
|
|
||||||
failAuth("unable to find JWT signing key", getCurrentException())
|
failAuth("unable to find JWT signing key", getCurrentException())
|
||||||
|
|
||||||
|
|
||||||
@ -142,7 +130,6 @@ proc validateJWT*(ctx: ApiAuthContext, jwt: JWT) =
|
|||||||
## Given a JWT, validate that it is a well-formed JWT, validate the issuer's
|
## Given a JWT, validate that it is a well-formed JWT, validate the issuer's
|
||||||
## signature on the token, and validate all the claims that it preesnts.
|
## signature on the token, and validate all the claims that it preesnts.
|
||||||
try:
|
try:
|
||||||
log().debug "Validating JWT: " & $jwt
|
|
||||||
if jwt.claims.iss.isNone: failAuth "Missing 'iss' claim."
|
if jwt.claims.iss.isNone: failAuth "Missing 'iss' claim."
|
||||||
let jwtIssuer = jwt.claims.iss.get
|
let jwtIssuer = jwt.claims.iss.get
|
||||||
|
|
||||||
@ -157,9 +144,6 @@ proc validateJWT*(ctx: ApiAuthContext, jwt: JWT) =
|
|||||||
if jwt.claims.exp.isNone: failAuth "Missing or invalid 'exp' claim."
|
if jwt.claims.exp.isNone: failAuth "Missing or invalid 'exp' claim."
|
||||||
|
|
||||||
if not ctx.validAudiences.contains(jwt.claims.aud.get):
|
if not ctx.validAudiences.contains(jwt.claims.aud.get):
|
||||||
log().debug(
|
|
||||||
"Valid audiences: $#\ttoken audience: $#" %
|
|
||||||
[$ctx.validAudiences, jwt.claims.aud.get])
|
|
||||||
failAuth "JWT is not for us (invalid audience)."
|
failAuth "JWT is not for us (invalid audience)."
|
||||||
|
|
||||||
let signingAlgorithm = jwt.header.alg.get
|
let signingAlgorithm = jwt.header.alg.get
|
||||||
|
Loading…
x
Reference in New Issue
Block a user