blob: 2fb89c3af73f602c68ae4cab19a2ded94638bf01 [file] [log] [blame]
defmodule JwtAuthTest do
use CouchTestCase
@moduletag :authentication
test "jwt auth with HMAC secret", _context do
secret = "zxczxc12zxczxc12"
server_config = [
%{
:section => "jwt_keys",
:key => "hmac:_default",
:value => :base64.encode(secret)
},
%{
:section => "jwt_auth",
:key => "allowed_algorithms",
:value => "HS256, HS384, HS512"
}
]
run_on_modified_server(server_config, fn -> test_fun("HS256", secret) end)
run_on_modified_server(server_config, fn -> test_fun("HS384", secret) end)
run_on_modified_server(server_config, fn -> test_fun("HS512", secret) end)
end
defmodule RSA do
require Record
Record.defrecord :public, :RSAPublicKey,
Record.extract(:RSAPublicKey, from_lib: "public_key/include/public_key.hrl")
Record.defrecord :private, :RSAPrivateKey,
Record.extract(:RSAPrivateKey, from_lib: "public_key/include/public_key.hrl")
end
test "jwt auth with RSA secret", _context do
require JwtAuthTest.RSA
private_key = :public_key.generate_key({:rsa, 2048, 17})
public_key = RSA.public(
modulus: RSA.private(private_key, :modulus),
publicExponent: RSA.private(private_key, :publicExponent))
public_pem = :public_key.pem_encode(
[:public_key.pem_entry_encode(
:SubjectPublicKeyInfo, public_key)])
public_pem = String.replace(public_pem, "\n", "\\n")
server_config = [
%{
:section => "jwt_keys",
:key => "rsa:_default",
:value => public_pem
},
%{
:section => "jwt_auth",
:key => "allowed_algorithms",
:value => "RS256, RS384, RS512"
}
]
run_on_modified_server(server_config, fn -> test_fun("RS256", private_key) end)
run_on_modified_server(server_config, fn -> test_fun("RS384", private_key) end)
run_on_modified_server(server_config, fn -> test_fun("RS512", private_key) end)
end
defmodule EC do
require Record
Record.defrecord :point, :ECPoint,
Record.extract(:ECPoint, from_lib: "public_key/include/public_key.hrl")
Record.defrecord :private, :ECPrivateKey,
Record.extract(:ECPrivateKey, from_lib: "public_key/include/public_key.hrl")
end
test "jwt auth with EC secret", _context do
require JwtAuthTest.EC
private_key = :public_key.generate_key({:namedCurve, :secp384r1})
point = EC.point(point: EC.private(private_key, :publicKey))
public_key = {point, EC.private(private_key, :parameters)}
public_pem = :public_key.pem_encode(
[:public_key.pem_entry_encode(
:SubjectPublicKeyInfo, public_key)])
public_pem = String.replace(public_pem, "\n", "\\n")
server_config = [
%{
:section => "jwt_keys",
:key => "ec:_default",
:value => public_pem
},
%{
:section => "jwt_auth",
:key => "allowed_algorithms",
:value => "ES256, ES384, ES512"
}
]
run_on_modified_server(server_config, fn -> test_fun("ES256", private_key) end)
run_on_modified_server(server_config, fn -> test_fun("ES384", private_key) end)
run_on_modified_server(server_config, fn -> test_fun("ES512", private_key) end)
end
def test_fun(alg, key) do
now = DateTime.to_unix(DateTime.utc_now())
{:ok, token} = :jwtf.encode(
{
[
{"alg", alg},
{"typ", "JWT"}
]
},
{
[
{"nbf", now - 60},
{"exp", now + 60},
{"sub", "couch@apache.org"},
{"_couchdb.roles", ["testing"]
}
]
}, key)
resp = Couch.get("/_session",
headers: [authorization: "Bearer #{token}"]
)
assert resp.body["userCtx"]["name"] == "couch@apache.org"
assert resp.body["userCtx"]["roles"] == ["testing"]
assert resp.body["info"]["authenticated"] == "jwt"
end
test "jwt auth without secret", _context do
resp = Couch.get("/_session")
assert resp.body["userCtx"]["name"] == "adm"
assert resp.body["info"]["authenticated"] == "default"
end
end