summaryrefslogtreecommitdiff
path: root/test/elixir/test/jwtauth_test.exs
blob: c50225cbd99ed1a0729ca8b9c5771f555bf9fdb4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
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
    {:ok, token} = :jwtf.encode({[{"alg", alg}, {"typ", "JWT"}]}, {[{"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