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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
|
defmodule JwtRolesClaimTest do
use CouchTestCase
@global_server_config [
%{
:section => "chttpd",
:key => "authentication_handlers",
:value => [
"{chttpd_auth, jwt_authentication_handler}, ",
"{chttpd_auth, cookie_authentication_handler}, ",
"{chttpd_auth, default_authentication_handler})"
] |> Enum.join
},
%{
:section => "jwt_keys",
:key => "hmac:myjwttestkey",
:value => ~w(
NTNv7j0TuYARvmNMmWXo6fKvM4o6nv/aUi9ryX38ZH+L1bkrnD1ObOQ8JAUmHCBq7
Iy7otZcyAagBLHVKvvYaIpmMuxmARQ97jUVG16Jkpkp1wXOPsrF9zwew6TpczyH
kHgX5EuLg2MeBuiT/qJACs1J0apruOOJCg/gOtkjB4c=
) |> Enum.join()
},
%{
:section => "jwt_keys",
:key => "hmac:myjwttestkey2",
:value => ~w(
VW5kb3VidGVkbHktRW5nYWdpbmctUm9hZHdheS0wMjk=
) |> Enum.join()
}
]
test "case: roles_claim_name (undefined) / roles_claim_path (undefined)" do
server_config = @global_server_config
run_on_modified_server(server_config, fn ->
test_roles(["_couchdb.roles_1", "_couchdb.roles_2"])
test_roles_as_string(["_couchdb_string.roles_1", "_couchdb_string.roles_2"])
end)
end
test "case: roles_claim_name (defined) / roles_claim_path (undefined)" do
server_config =
[
%{
:section => "jwt_auth",
:key => "roles_claim_name",
:value => "my._couchdb.roles"
}
] ++ @global_server_config
run_on_modified_server(server_config, fn ->
test_roles(["my._couchdb.roles_1", "my._couchdb.roles_2"])
test_roles_as_string(["my._couchdb_string.roles_1", "my._couchdb_string.roles_2"])
end)
end
test "case: roles_claim_name (undefined) / roles_claim_path (defined)" do
server_config =
[
%{
:section => "jwt_auth",
:key => "roles_claim_path",
:value => "foo.bar\\.zonk.baz\\.buu.baa.baa\\.bee.roles"
}
] ++ @global_server_config
run_on_modified_server(server_config, fn ->
test_roles(["my_nested_role_1", "my_nested_role_2"])
test_roles_as_string(["my_nested_string_role_1", "my_nested_string_role_2"])
end)
end
test "case: roles_claim_name (defined) / roles_claim_path (defined)" do
server_config =
[
%{
:section => "jwt_auth",
:key => "roles_claim_name",
:value => "my._couchdb.roles"
},
%{
:section => "jwt_auth",
:key => "roles_claim_path",
:value => "foo.bar\\.zonk.baz\\.buu.baa.baa\\.bee.roles"
}
] ++ @global_server_config
run_on_modified_server(server_config, fn ->
test_roles(["my_nested_role_1", "my_nested_role_2"])
test_roles_as_string(["my_nested_string_role_1", "my_nested_string_role_2"])
end)
end
test "case: roles_claim_path with bad input" do
server_config =
[
%{
:section => "jwt_auth",
:key => "roles_claim_path",
:value => "<<foo.bar\\.zonk.baz\\.buu.baa.baa\\.bee.roles"
}
] ++ @global_server_config
run_on_modified_server(server_config, fn ->
test_roles_with_bad_input()
end)
server_config =
[
%{
:section => "jwt_auth",
:key => "roles_claim_path",
:value => "foo.bar\\.zonk.baz\\.buu.baa.baa\\.bee.roles>>"
}
] ++ @global_server_config
run_on_modified_server(server_config, fn ->
test_roles_with_bad_input()
end)
server_config =
[
%{
:section => "jwt_auth",
:key => "roles_claim_path",
:value => "123456"
}
] ++ @global_server_config
run_on_modified_server(server_config, fn ->
test_roles_with_bad_input()
end)
end
def test_roles(roles) do
token = ~w(
eyJ0eXAiOiJKV1QiLCJraWQiOiJteWp3dHRlc3RrZXkiLCJhbGciOiJIUzI1NiJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRyd
WUsImlhdCI6MTY1NTI5NTgxMCwiZXhwIjoxNzU1Mjk5NDEwLCJteSI6eyJuZXN0ZW
QiOnsiX2NvdWNoZGIucm9sZXMiOlsibXlfbmVzdGVkX2NvdWNoZGIucm9sZXNfMSI
sIm15X25lc3RlZF9jb3VjaGRiLnJvbGVzXzEiXX19LCJfY291Y2hkYi5yb2xlcyI6
WyJfY291Y2hkYi5yb2xlc18xIiwiX2NvdWNoZGIucm9sZXNfMiJdLCJteS5fY291Y
2hkYi5yb2xlcyI6WyJteS5fY291Y2hkYi5yb2xlc18xIiwibXkuX2NvdWNoZGIucm
9sZXNfMiJdLCJmb28iOnsiYmFyLnpvbmsiOnsiYmF6LmJ1dSI6eyJiYWEiOnsiYmF
hLmJlZSI6eyJyb2xlcyI6WyJteV9uZXN0ZWRfcm9sZV8xIiwibXlfbmVzdGVkX3Jv
bGVfMiJdfX19fX19.F6kQK-FK0z1kP01bTyw-moXfy2klWfubgF7x7Xitd-0) |> Enum.join()
resp =
Couch.get("/_session",
headers: [authorization: "Bearer #{token}"]
)
assert resp.body["userCtx"]["name"] == "1234567890"
assert resp.body["userCtx"]["roles"] == roles
assert resp.body["info"]["authenticated"] == "jwt"
end
def test_roles_as_string(roles) do
# Different token
token = ~w(
eyJ0eXAiOiJKV1QiLCJraWQiOiJteWp3dHRlc3RrZXkyIiwiYWxnIjoiSFMyNTYifQ.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWU
sImlhdCI6MTY1NTI5NTgxMCwiZXhwIjoxNzU1Mjk5NDEwLCJteSI6eyJuZXN0ZWQiOn
siX2NvdWNoZGIucm9sZXMiOiJteV9uZXN0ZWRfY291Y2hkYl9zdHJpbmcucm9sZXNfM
SwgbXlfbmVzdGVkX2NvdWNoZGJfc3RyaW5nLnJvbGVzXzEifX0sIl9jb3VjaGRiLnJv
bGVzIjoiX2NvdWNoZGJfc3RyaW5nLnJvbGVzXzEsX2NvdWNoZGJfc3RyaW5nLnJvbGV
zXzIiLCJteS5fY291Y2hkYi5yb2xlcyI6Im15Ll9jb3VjaGRiX3N0cmluZy5yb2xlc1
8xLCBteS5fY291Y2hkYl9zdHJpbmcucm9sZXNfMiIsImZvbyI6eyJiYXIuem9uayI6e
yJiYXouYnV1Ijp7ImJhYSI6eyJiYWEuYmVlIjp7InJvbGVzIjoibXlfbmVzdGVkX3N0
cmluZ19yb2xlXzEsIG15X25lc3RlZF9zdHJpbmdfcm9sZV8yIn19fX19fQ.rzaLmcA2
0R291XuGYNNTM9ypGL3UD_GlVp3DmBtWrZI
) |> Enum.join()
resp =
Couch.get("/_session",
headers: [authorization: "Bearer #{token}"]
)
assert resp.body["userCtx"]["name"] == "1234567890"
assert resp.body["userCtx"]["roles"] == roles
assert resp.body["info"]["authenticated"] == "jwt"
end
def test_roles_with_bad_input() do
token = ~w(
eyJ0eXAiOiJKV1QiLCJraWQiOiJteWp3dHRlc3RrZXkiLCJhbGciOiJIUzI1NiJ9.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRyd
WUsImlhdCI6MTY1NTI5NTgxMCwiZXhwIjoxNzU1Mjk5NDEwLCJteSI6eyJuZXN0ZW
QiOnsiX2NvdWNoZGIucm9sZXMiOlsibXlfbmVzdGVkX2NvdWNoZGIucm9sZXNfMSI
sIm15X25lc3RlZF9jb3VjaGRiLnJvbGVzXzEiXX19LCJfY291Y2hkYi5yb2xlcyI6
WyJfY291Y2hkYi5yb2xlc18xIiwiX2NvdWNoZGIucm9sZXNfMiJdLCJteS5fY291Y
2hkYi5yb2xlcyI6WyJteS5fY291Y2hkYi5yb2xlc18xIiwibXkuX2NvdWNoZGIucm
9sZXNfMiJdLCJmb28iOnsiYmFyLnpvbmsiOnsiYmF6LmJ1dSI6eyJiYWEiOnsiYmF
hLmJlZSI6eyJyb2xlcyI6WyJteV9uZXN0ZWRfcm9sZV8xIiwibXlfbmVzdGVkX3Jv
bGVfMiJdfX19fX19.F6kQK-FK0z1kP01bTyw-moXfy2klWfubgF7x7Xitd-0) |> Enum.join()
resp =
Couch.get("/_session",
headers: [authorization: "Bearer #{token}"]
)
assert resp.status_code == 404
end
end
|