diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..e562f49 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,33 @@ +language: c + +# https://docs.travis-ci.com/user/caching/ +# +# Caching the whole nim folder is better than relying on ccache - this way, we +# skip the expensive bootstrap process and linking +cache: + directories: + - nim + +os: + - linux + - osx + +install: + # check version of remote branch + - "export NIMVER=$(git ls-remote https://github.com/nim-lang/nim.git HEAD | cut -f 1)" + + # after building nim, wipe csources to save on cache space + - "{ [ -f nim/$NIMVER/bin/nim ] && [ -f nim/$NIMVER/bin/nimble ] ; } || + { rm -rf nim ; + mkdir -p nim ; + git clone --depth=1 https://github.com/nim-lang/nim.git nim/$NIMVER ; + cd nim/$NIMVER ; + sh build_all.sh ; + rm -rf csources ; + cd ../.. ; + }" + - "export PATH=$PWD/nim/$NIMVER/bin:$HOME/.nimble/bin:$PATH" + +script: + - nimble install -y + - nimble test diff --git a/README.md b/README.md index 7d50f39..41af599 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -JWT Implementation for Nim-lang +JWT Implementation for Nim-lang [![Build Status](https://travis-ci.org/yglukhov/nim-jwt.svg?branch=master)](https://travis-ci.org/yglukhov/nim-jwt) =============================== This is a implementation of JSON Web Tokens for Nim, it allows for the following operations to be performed: diff --git a/src/jwt.nim b/jwt.nim similarity index 94% rename from src/jwt.nim rename to jwt.nim index e759a3e..05e18c2 100644 --- a/src/jwt.nim +++ b/jwt.nim @@ -1,8 +1,8 @@ -import future, json, strutils, tables, times, sequtils +import json, strutils, tables, times, sequtils -from private/crypto import nil +from jwt/private/crypto import nil -import private/claims, private/jose, private/utils +import jwt/private/[claims, jose, utils] type InvalidToken* = object of Exception @@ -98,7 +98,7 @@ proc signString*(toSign: string, secret: string, algorithm: SignatureAlgorithm = return rsSign(crypto.EVP_sha384()) else: raise newException(UnsupportedAlgorithm, $algorithm & " isn't supported") - result = join(signature.map((i: uint8) => (toHex(BiggestInt(i), 2))), "") + result = join(signature.mapIt(toHex(BiggestInt(it), 2)), "") # Verify that the token is not tampered with proc verifySignature*(data: string, signature: string, secret: string): bool = diff --git a/jwt.nimble b/jwt.nimble index 6d783e7..9d9bf40 100644 --- a/jwt.nimble +++ b/jwt.nimble @@ -8,4 +8,4 @@ srcDir = "src" # Deps requires "nim >= 0.19.0" - +requires "https://github.com/yglukhov/linktools" diff --git a/src/private/claims.nim b/jwt/private/claims.nim similarity index 97% rename from src/private/claims.nim rename to jwt/private/claims.nim index 288a722..294a022 100644 --- a/src/private/claims.nim +++ b/jwt/private/claims.nim @@ -1,4 +1,4 @@ -import future, json, sequtils, strutils, times, tables +import json, sequtils, strutils, times, tables import utils @@ -72,7 +72,7 @@ proc newTimeClaim*(k: ClaimKind, i: int64): Claim = # Returns the claimKeyms value as a time proc getClaimTime*(c: Claim): Time = - result = fromSeconds(c.node.num) + result = fromUnix(c.node.num) # NBF proc newNBF*(s: string): Claim = return newTimeClaim(NBF, s) diff --git a/src/private/crypto.nim b/jwt/private/crypto.nim similarity index 91% rename from src/private/crypto.nim rename to jwt/private/crypto.nim index 27e2725..d7426e0 100644 --- a/src/private/crypto.nim +++ b/jwt/private/crypto.nim @@ -1,9 +1,21 @@ -import openssl +import openssl, linktools + +# TODO: Linkage flags should probably need more attention because of different +# openssl versions. E.g. DigestSign* functions are not available in old openssl. +when defined(macosx): + const libcrypto = "crypto.35" +else: + const libcrypto = "crypto" + +{.passL: "-l" & libcrypto.} + export EVP_PKEY_RSA const HMAC_MAX_MD_CBLOCK* = 128 +const sslIsOld = libHasSymbol(libcrypto, "EVP_MD_CTX_create") + type EVP_MD* = SslPtr EVP_MD_CTX* = SslPtr @@ -35,7 +47,7 @@ proc PEM_read_bio_PrivateKey*(bp: BIO, x: ptr EVP_PKEY, proc EVP_PKEY_free*(p: EVP_PKEY) {.cdecl, importc.} -when defined(macosx): +when sslIsOld: proc EVP_MD_CTX_create*(): EVP_MD_CTX {.cdecl, importc.} proc EVP_MD_CTX_destroy*(ctx: EVP_MD_CTX) {.cdecl, importc.} else: diff --git a/src/private/jose.nim b/jwt/private/jose.nim similarity index 100% rename from src/private/jose.nim rename to jwt/private/jose.nim diff --git a/src/private/utils.nim b/jwt/private/utils.nim similarity index 100% rename from src/private/utils.nim rename to jwt/private/utils.nim diff --git a/tests/t_claims.nim b/tests/t_claims.nim index 29a8875..88eb629 100644 --- a/tests/t_claims.nim +++ b/tests/t_claims.nim @@ -1,21 +1,21 @@ import json, unittest -import jwt +import ../jwt suite "Claim ops": test "Create claims from JSON": - let asJson = %{ - "iss": %"jane", - "sub": %"john", - "nbf": %1234, - "iat": %1234, - "exp": %1234, - "jti": %"token-id", - "foo": %{"bar": %1} - } - let claims = asJson.toClaims - let toJson = %claims + let asJson = %{ + "iss": %"jane", + "sub": %"john", + "nbf": %1234, + "iat": %1234, + "exp": %1234, + "jti": %"token-id", + "foo": %{"bar": %1} + } + let claims = asJson.toClaims + let toJson = %claims - assert asJson.len == toJson.len - for k, v in asJson: - assert v == toJson[k] + assert asJson.len == toJson.len + for k, v in asJson: + assert v == toJson[k] diff --git a/tests/t_jwt.nim b/tests/t_jwt.nim index 19ee11e..b9083be 100644 --- a/tests/t_jwt.nim +++ b/tests/t_jwt.nim @@ -1,7 +1,7 @@ import json, times, unittest from times import nil -import jwt +import ../jwt proc getToken(claims: JsonNode = newJObject(), header: JsonNode = newJObject()): JWT = let claims = claims.toClaims @@ -32,14 +32,14 @@ suite "Token tests": test "NBF Check": let - now = getTime().toSeconds.int + 60 + now = getTime().toUnix.int + 60 token = getToken(claims = %{"nbf": %now}) expect(InvalidToken): token.verifyTimeClaims test "EXP Check": let - now = getTime().toSeconds.int - 60 + now = getTime().toUnix.int - 60 token = getToken(claims = %{"exp": %now}) expect(InvalidToken): token.verifyTimeClaims