onlyoffice-docs_integration_sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/lib/onlyoffice/docs_integration_sdk/document_editor/config.rb +1479 -0
- data/lib/onlyoffice/docs_integration_sdk/document_editor/config_test.rb +1713 -0
- data/lib/onlyoffice/docs_integration_sdk/document_editor.rb +29 -0
- data/lib/onlyoffice/docs_integration_sdk/document_server/client/command.rb +417 -0
- data/lib/onlyoffice/docs_integration_sdk/document_server/client/command_test.rb +672 -0
- data/lib/onlyoffice/docs_integration_sdk/document_server/client/conversion.rb +477 -0
- data/lib/onlyoffice/docs_integration_sdk/document_server/client/conversion_test.rb +682 -0
- data/lib/onlyoffice/docs_integration_sdk/document_server/client/healthcheck.rb +101 -0
- data/lib/onlyoffice/docs_integration_sdk/document_server/client/healthcheck_test.rb +209 -0
- data/lib/onlyoffice/docs_integration_sdk/document_server/client/jwt.rb +116 -0
- data/lib/onlyoffice/docs_integration_sdk/document_server/client/jwt_test.rb +70 -0
- data/lib/onlyoffice/docs_integration_sdk/document_server/client/response.rb +73 -0
- data/lib/onlyoffice/docs_integration_sdk/document_server/client/response_test.rb +49 -0
- data/lib/onlyoffice/docs_integration_sdk/document_server/client/service.rb +44 -0
- data/lib/onlyoffice/docs_integration_sdk/document_server/client/ua.rb +31 -0
- data/lib/onlyoffice/docs_integration_sdk/document_server/client/ua_test.rb +35 -0
- data/lib/onlyoffice/docs_integration_sdk/document_server/client.rb +321 -0
- data/lib/onlyoffice/docs_integration_sdk/document_server/client_test.rb +1259 -0
- data/lib/onlyoffice/docs_integration_sdk/document_server.rb +29 -0
- data/lib/onlyoffice/docs_integration_sdk/document_storage/callback.rb +276 -0
- data/lib/onlyoffice/docs_integration_sdk/document_storage/callback_test.rb +291 -0
- data/lib/onlyoffice/docs_integration_sdk/document_storage.rb +29 -0
- data/lib/onlyoffice/docs_integration_sdk/jwt.rb +448 -0
- data/lib/onlyoffice/docs_integration_sdk/jwt_test.rb +598 -0
- data/lib/onlyoffice/docs_integration_sdk/test_test.rb +113 -0
- data/lib/onlyoffice/docs_integration_sdk/version.rb +26 -0
- data/lib/onlyoffice/docs_integration_sdk/version_test.rb +33 -0
- data/lib/onlyoffice/docs_integration_sdk.rb +31 -0
- data/lib/onlyoffice.rb +21 -0
- metadata +283 -0
@@ -0,0 +1,598 @@
|
|
1
|
+
#
|
2
|
+
# (c) Copyright Ascensio System SIA 2025
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
# typed: true
|
18
|
+
# frozen_string_literal: true
|
19
|
+
|
20
|
+
require "test/unit"
|
21
|
+
require_relative "jwt"
|
22
|
+
|
23
|
+
module Onlyoffice
|
24
|
+
module DocsIntegrationSdk
|
25
|
+
class JwtTest < ::Test::Unit::TestCase
|
26
|
+
extend T::Sig
|
27
|
+
|
28
|
+
def test_initialize_initializes_with_default_values
|
29
|
+
j = Jwt.new(secret: "***")
|
30
|
+
assert_equal("***", j.secret)
|
31
|
+
assert_equal("HS256", j.algorithm)
|
32
|
+
assert_equal(2, j.claims.length)
|
33
|
+
|
34
|
+
e = T.cast(j.claims[0], Jwt::ExpClaim)
|
35
|
+
assert_equal(300, e.ttl)
|
36
|
+
assert_equal(30, e.leeway)
|
37
|
+
|
38
|
+
_ = T.cast(j.claims[1], Jwt::IatClaim)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_initialize_initializes_with_custom_values
|
42
|
+
j = Jwt.new(
|
43
|
+
secret: "***",
|
44
|
+
algorithm: "HS512",
|
45
|
+
claims: [Jwt::ExpClaim.new(ttl: 600, leeway: 60)],
|
46
|
+
)
|
47
|
+
assert_equal("***", j.secret)
|
48
|
+
assert_equal("HS512", j.algorithm)
|
49
|
+
assert_equal(1, j.claims.length)
|
50
|
+
|
51
|
+
e = T.cast(j.claims[0], Jwt::ExpClaim)
|
52
|
+
assert_equal(600, e.ttl)
|
53
|
+
assert_equal(60, e.leeway)
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_initialize_initializes_claims_by_value
|
57
|
+
c = T.let([Jwt::ExpClaim.new], T::Array[Jwt::Claim])
|
58
|
+
|
59
|
+
j = Jwt.new(secret: "***", algorithm: "HS512", claims: c)
|
60
|
+
|
61
|
+
c.push(Jwt::IatClaim.new)
|
62
|
+
|
63
|
+
assert_equal(1, j.claims.length)
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_encode_encodes_with_an_empty_secret
|
67
|
+
j = Jwt.new(secret: "", algorithm: "HS256", claims: [])
|
68
|
+
|
69
|
+
t = j.encode({"v" => 1})
|
70
|
+
|
71
|
+
d = decode(j, t)
|
72
|
+
assert_equal(2, d.length)
|
73
|
+
|
74
|
+
p = d[0]
|
75
|
+
assert_equal(1, p.keys.length)
|
76
|
+
assert_equal(1, p["v"])
|
77
|
+
|
78
|
+
h = d[1]
|
79
|
+
assert_equal(1, h.keys.length)
|
80
|
+
assert_equal(j.algorithm, h["alg"])
|
81
|
+
end
|
82
|
+
|
83
|
+
def test_encode_encodes_with_a_secret
|
84
|
+
j = Jwt.new(secret: "***", algorithm: "HS256", claims: [])
|
85
|
+
|
86
|
+
t = j.encode({"v" => 1})
|
87
|
+
|
88
|
+
d = decode(j, t)
|
89
|
+
assert_equal(2, d.length)
|
90
|
+
|
91
|
+
p = d[0]
|
92
|
+
assert_equal(1, p.keys.length)
|
93
|
+
assert_equal(1, p["v"])
|
94
|
+
|
95
|
+
h = d[1]
|
96
|
+
assert_equal(1, h.keys.length)
|
97
|
+
assert_equal(j.algorithm, h["alg"])
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_encode_raises_an_error_if_the_algorithm_is_absent
|
101
|
+
j = Jwt.new(secret: "***", algorithm: "", claims: [])
|
102
|
+
|
103
|
+
assert_raise_with_message(JWT::EncodeError, "Unsupported signing method") do
|
104
|
+
j.encode({v: 1})
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def test_encode_raises_an_error_if_the_algorithm_is_unsupported
|
109
|
+
j = Jwt.new(secret: "***", algorithm: "Unknown", claims: [])
|
110
|
+
|
111
|
+
assert_raise_with_message(JWT::EncodeError, "Unsupported signing method") do
|
112
|
+
j.encode({v: 1})
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def test_encode_includes_the_exp_claim
|
117
|
+
j = Jwt.new(
|
118
|
+
secret: "***",
|
119
|
+
algorithm: "HS256",
|
120
|
+
claims: [Jwt::ExpClaim.new(ttl: 300, leeway: 0)],
|
121
|
+
)
|
122
|
+
|
123
|
+
t = j.encode({"v" => 1})
|
124
|
+
|
125
|
+
d = decode(j, t)
|
126
|
+
assert_equal(2, d.length)
|
127
|
+
|
128
|
+
p = d[0]
|
129
|
+
assert_equal(2, p.keys.length)
|
130
|
+
assert_equal(1, p["v"])
|
131
|
+
assert_in_delta(Time.now.utc.to_i + 300, p["exp"], 1)
|
132
|
+
|
133
|
+
h = d[1]
|
134
|
+
assert_equal(1, h.keys.length)
|
135
|
+
assert_equal(j.algorithm, h["alg"])
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_encode_ignores_the_exp_claim_if_the_ttl_is_absent
|
139
|
+
j = Jwt.new(
|
140
|
+
secret: "***",
|
141
|
+
algorithm: "HS256",
|
142
|
+
claims: [Jwt::ExpClaim.new(ttl: 0, leeway: 0)],
|
143
|
+
)
|
144
|
+
|
145
|
+
t = j.encode({"v" => 1})
|
146
|
+
|
147
|
+
d = decode(j, t)
|
148
|
+
assert_equal(2, d.length)
|
149
|
+
|
150
|
+
p = d[0]
|
151
|
+
assert_equal(1, p.keys.length)
|
152
|
+
assert_equal(1, p["v"])
|
153
|
+
|
154
|
+
h = d[1]
|
155
|
+
assert_equal(1, h.keys.length)
|
156
|
+
assert_equal(j.algorithm, h["alg"])
|
157
|
+
end
|
158
|
+
|
159
|
+
def test_encode_ignores_the_exp_claim_if_only_the_ttl_is_present
|
160
|
+
j = Jwt.new(secret: "***", algorithm: "HS256", claims: [])
|
161
|
+
|
162
|
+
t = j.encode({"v" => 1})
|
163
|
+
|
164
|
+
d = decode(j, t)
|
165
|
+
assert_equal(2, d.length)
|
166
|
+
|
167
|
+
p = d[0]
|
168
|
+
assert_equal(1, p.keys.length)
|
169
|
+
assert_equal(1, p["v"])
|
170
|
+
|
171
|
+
h = d[1]
|
172
|
+
assert_equal(1, h.keys.length)
|
173
|
+
assert_equal(j.algorithm, h["alg"])
|
174
|
+
end
|
175
|
+
|
176
|
+
def test_encode_includes_the_iat_claim
|
177
|
+
j = Jwt.new(
|
178
|
+
secret: "***",
|
179
|
+
algorithm: "HS256",
|
180
|
+
claims: [Jwt::IatClaim.new],
|
181
|
+
)
|
182
|
+
|
183
|
+
t = j.encode({"v" => 1})
|
184
|
+
|
185
|
+
d = decode(j, t)
|
186
|
+
assert_equal(2, d.length)
|
187
|
+
|
188
|
+
p = d[0]
|
189
|
+
assert_equal(2, p.keys.length)
|
190
|
+
assert_equal(1, p["v"])
|
191
|
+
assert_in_delta(Time.now.utc.to_i, p["iat"], 1)
|
192
|
+
|
193
|
+
h = d[1]
|
194
|
+
assert_equal(1, h.keys.length)
|
195
|
+
assert_equal(j.algorithm, h["alg"])
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_encode_includes_multiple_claims
|
199
|
+
j = Jwt.new(
|
200
|
+
secret: "***",
|
201
|
+
algorithm: "HS256",
|
202
|
+
claims: [
|
203
|
+
Jwt::ExpClaim.new(ttl: 300, leeway: 0),
|
204
|
+
Jwt::IatClaim.new,
|
205
|
+
],
|
206
|
+
)
|
207
|
+
|
208
|
+
t = j.encode({"v" => 1})
|
209
|
+
|
210
|
+
d = decode(j, t)
|
211
|
+
assert_equal(2, d.length)
|
212
|
+
|
213
|
+
p = d[0]
|
214
|
+
assert_equal(3, p.keys.length)
|
215
|
+
assert_equal(1, p["v"])
|
216
|
+
assert_in_delta(Time.now.utc.to_i + 300, p["exp"], 1)
|
217
|
+
assert_in_delta(Time.now.utc.to_i, p["iat"], 1)
|
218
|
+
|
219
|
+
h = d[1]
|
220
|
+
assert_equal(1, h.keys.length)
|
221
|
+
assert_equal(j.algorithm, h["alg"])
|
222
|
+
end
|
223
|
+
|
224
|
+
def test_encode_does_not_mutate_the_payload
|
225
|
+
j = Jwt.new(
|
226
|
+
secret: "***",
|
227
|
+
algorithm: "HS256",
|
228
|
+
claims: [Jwt::ExpClaim.new(ttl: 300, leeway: 0)],
|
229
|
+
)
|
230
|
+
|
231
|
+
p = {"v" => 1, "exp" => 1}
|
232
|
+
t = j.encode(p)
|
233
|
+
assert_equal(2, p.keys.length)
|
234
|
+
assert_equal(1, p["v"])
|
235
|
+
assert_equal(1, p["exp"])
|
236
|
+
|
237
|
+
d = decode(j, t)
|
238
|
+
assert_equal(2, d.length)
|
239
|
+
|
240
|
+
p = d[0]
|
241
|
+
assert_equal(2, p.keys.length)
|
242
|
+
assert_equal(1, p["v"])
|
243
|
+
assert_in_delta(Time.now.utc.to_i + 300, p["exp"], 1)
|
244
|
+
|
245
|
+
h = d[1]
|
246
|
+
assert_equal(1, h.keys.length)
|
247
|
+
assert_equal(j.algorithm, h["alg"])
|
248
|
+
end
|
249
|
+
|
250
|
+
def test_encode_body_encodes
|
251
|
+
j = Jwt.new(secret: "***", algorithm: "HS256", claims: [])
|
252
|
+
|
253
|
+
b = j.encode_body({"v" => 1})
|
254
|
+
assert_equal(2, b.keys.length)
|
255
|
+
assert_equal(1, b["v"])
|
256
|
+
|
257
|
+
d = decode(j, b["token"])
|
258
|
+
assert_equal(2, d.length)
|
259
|
+
|
260
|
+
p = d[0]
|
261
|
+
assert_equal(1, p.keys.length)
|
262
|
+
assert_equal(1, p["v"])
|
263
|
+
|
264
|
+
h = d[1]
|
265
|
+
assert_equal(1, h.keys.length)
|
266
|
+
assert_equal(j.algorithm, h["alg"])
|
267
|
+
end
|
268
|
+
|
269
|
+
def test_encode_body_does_not_mutate_the_payload
|
270
|
+
j = Jwt.new(secret: "***", algorithm: "HS256", claims: [])
|
271
|
+
|
272
|
+
p = {"v" => 1, "token" => "***"}
|
273
|
+
b = j.encode_body(p)
|
274
|
+
assert_equal(2, p.keys.length)
|
275
|
+
assert_equal(1, p["v"])
|
276
|
+
assert_equal("***", p["token"])
|
277
|
+
|
278
|
+
d = decode(j, b["token"])
|
279
|
+
assert_equal(2, d.length)
|
280
|
+
|
281
|
+
p = d[0]
|
282
|
+
assert_equal(2, p.keys.length)
|
283
|
+
assert_equal(1, p["v"])
|
284
|
+
assert_equal("***", p["token"])
|
285
|
+
|
286
|
+
h = d[1]
|
287
|
+
assert_equal(1, h.keys.length)
|
288
|
+
assert_equal(j.algorithm, h["alg"])
|
289
|
+
end
|
290
|
+
|
291
|
+
def test_encode_header_encodes
|
292
|
+
j = Jwt.new(secret: "***", algorithm: "HS256", claims: [])
|
293
|
+
|
294
|
+
h = j.encode_header("v")
|
295
|
+
|
296
|
+
d = decode(j, h)
|
297
|
+
assert_equal(2, d.length)
|
298
|
+
|
299
|
+
p = d[0]
|
300
|
+
assert_equal(1, p.keys.length)
|
301
|
+
assert_equal("v", p["payload"])
|
302
|
+
|
303
|
+
h = d[1]
|
304
|
+
assert_equal(1, h.keys.length)
|
305
|
+
assert_equal(j.algorithm, h["alg"])
|
306
|
+
end
|
307
|
+
|
308
|
+
def test_encode_uri_encodes
|
309
|
+
j = Jwt.new(secret: "***", algorithm: "HS256", claims: [])
|
310
|
+
|
311
|
+
u = T.cast(URI.parse("http://localhost:8080/"), URI::HTTP)
|
312
|
+
n = j.encode_uri(u)
|
313
|
+
|
314
|
+
q = T.cast(n.query, String)
|
315
|
+
f = URI.decode_www_form(q)
|
316
|
+
|
317
|
+
c = T.cast(f.assoc("token"), [String, String])
|
318
|
+
t = c[1]
|
319
|
+
|
320
|
+
d = decode(j, t)
|
321
|
+
assert_equal(2, d.length)
|
322
|
+
|
323
|
+
p = d[0]
|
324
|
+
assert_equal(1, p.keys.length)
|
325
|
+
assert_equal(u.to_s, p["url"])
|
326
|
+
|
327
|
+
h = d[1]
|
328
|
+
assert_equal(1, h.keys.length)
|
329
|
+
assert_equal(j.algorithm, h["alg"])
|
330
|
+
end
|
331
|
+
|
332
|
+
def test_encode_uri_preserves_the_query
|
333
|
+
j = Jwt.new(secret: "***", algorithm: "HS256", claims: [])
|
334
|
+
|
335
|
+
u = T.cast(URI.parse("http://localhost:8080/?v=1"), URI::HTTP)
|
336
|
+
n = j.encode_uri(u)
|
337
|
+
|
338
|
+
q = T.cast(n.query, String)
|
339
|
+
f = URI.decode_www_form(q)
|
340
|
+
|
341
|
+
c = T.cast(f.assoc("v"), [String, String])
|
342
|
+
assert_equal(["v", "1"], c)
|
343
|
+
|
344
|
+
c = T.cast(f.assoc("token"), [String, String])
|
345
|
+
t = c[1]
|
346
|
+
|
347
|
+
d = decode(j, t)
|
348
|
+
assert_equal(2, d.length)
|
349
|
+
|
350
|
+
p = d[0]
|
351
|
+
assert_equal(1, p.keys.length)
|
352
|
+
assert_equal(u.to_s, p["url"])
|
353
|
+
|
354
|
+
h = d[1]
|
355
|
+
assert_equal(1, h.keys.length)
|
356
|
+
assert_equal(j.algorithm, h["alg"])
|
357
|
+
end
|
358
|
+
|
359
|
+
def test_encode_uri_does_not_mutate_the_query
|
360
|
+
j = Jwt.new(secret: "***", algorithm: "HS256", claims: [])
|
361
|
+
|
362
|
+
u = T.cast(URI.parse("http://localhost:8080/"), URI::HTTP)
|
363
|
+
n = j.encode_uri(u)
|
364
|
+
|
365
|
+
q = u.query
|
366
|
+
assert_nil(q)
|
367
|
+
|
368
|
+
q = T.cast(n.query, String)
|
369
|
+
f = URI.decode_www_form(q)
|
370
|
+
|
371
|
+
c = T.cast(f.assoc("token"), [String, String])
|
372
|
+
t = c[1]
|
373
|
+
|
374
|
+
d = decode(j, t)
|
375
|
+
assert_equal(2, d.length)
|
376
|
+
|
377
|
+
p = d[0]
|
378
|
+
assert_equal(1, p.keys.length)
|
379
|
+
assert_equal(u.to_s, p["url"])
|
380
|
+
|
381
|
+
h = d[1]
|
382
|
+
assert_equal(1, h.keys.length)
|
383
|
+
assert_equal(j.algorithm, h["alg"])
|
384
|
+
end
|
385
|
+
|
386
|
+
def test_decode_decodes
|
387
|
+
j = Jwt.new(secret: "***", algorithm: "HS256", claims: [])
|
388
|
+
|
389
|
+
t = j.encode({"v" => 1})
|
390
|
+
|
391
|
+
p = j.decode(t)
|
392
|
+
assert_equal(1, p.keys.length)
|
393
|
+
assert_equal(1, p["v"])
|
394
|
+
end
|
395
|
+
|
396
|
+
def test_decode_does_not_include_claims_in_the_payload
|
397
|
+
j = Jwt.new(
|
398
|
+
secret: "***",
|
399
|
+
algorithm: "HS256",
|
400
|
+
claims: [
|
401
|
+
Jwt::ExpClaim.new(ttl: 300, leeway: 0),
|
402
|
+
Jwt::IatClaim.new,
|
403
|
+
],
|
404
|
+
)
|
405
|
+
|
406
|
+
t = j.encode({"v" => 1})
|
407
|
+
|
408
|
+
p = j.decode(t)
|
409
|
+
assert_equal(1, p.keys.length)
|
410
|
+
assert_equal(1, p["v"])
|
411
|
+
end
|
412
|
+
|
413
|
+
def test_decode_raises_an_error_if_the_token_is_empty
|
414
|
+
j = Jwt.new(secret: "***", algorithm: "HS256", claims: [])
|
415
|
+
|
416
|
+
assert_raise_with_message(JWT::DecodeError, "Not enough or too many segments") do
|
417
|
+
j.decode("")
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
def test_decode_raises_an_error_if_the_token_is_invalid
|
422
|
+
j = Jwt.new(secret: "***", algorithm: "HS256", claims: [])
|
423
|
+
|
424
|
+
assert_raise_with_message(JWT::DecodeError, "Not enough or too many segments") do
|
425
|
+
j.decode("invalid")
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
429
|
+
def test_decode_raises_an_error_if_a_different_algorithm_is_used
|
430
|
+
j = Jwt.new(secret: "***", algorithm: "HS256", claims: [])
|
431
|
+
|
432
|
+
t = j.encode({"v" => 1})
|
433
|
+
|
434
|
+
j = Jwt.new(secret: "***", algorithm: "HS512", claims: [])
|
435
|
+
|
436
|
+
assert_raise_with_message(JWT::IncorrectAlgorithm, "Expected a different algorithm") do
|
437
|
+
j.decode(t)
|
438
|
+
end
|
439
|
+
end
|
440
|
+
|
441
|
+
def test_decode_raises_an_error_if_the_signature_has_expired
|
442
|
+
j = Jwt.new(
|
443
|
+
secret: "***",
|
444
|
+
algorithm: "HS256",
|
445
|
+
claims: [Jwt::ExpClaim.new(ttl: 1, leeway: 0)],
|
446
|
+
)
|
447
|
+
|
448
|
+
t = j.encode({"v" => 1})
|
449
|
+
|
450
|
+
sleep(1)
|
451
|
+
|
452
|
+
assert_raise_with_message(JWT::ExpiredSignature, "Signature has expired") do
|
453
|
+
j.decode(t)
|
454
|
+
end
|
455
|
+
end
|
456
|
+
|
457
|
+
def test_decode_does_not_raise_an_error_if_the_signature_has_expired_within_the_leeway
|
458
|
+
j = Jwt.new(
|
459
|
+
secret: "***",
|
460
|
+
algorithm: "HS256",
|
461
|
+
claims: [Jwt::ExpClaim.new(ttl: 1, leeway: 10)],
|
462
|
+
)
|
463
|
+
|
464
|
+
t = j.encode({"v" => 1})
|
465
|
+
|
466
|
+
sleep(1)
|
467
|
+
|
468
|
+
p = j.decode(t)
|
469
|
+
assert_equal(1, p.keys.length)
|
470
|
+
assert_equal(1, p["v"])
|
471
|
+
end
|
472
|
+
|
473
|
+
def test_decode_body_decodes
|
474
|
+
j = Jwt.new(secret: "***", algorithm: "HS256", claims: [])
|
475
|
+
|
476
|
+
b = j.encode_body({"v" => 1})
|
477
|
+
|
478
|
+
b = j.decode_body(b)
|
479
|
+
assert_equal(1, b.keys.length)
|
480
|
+
assert_equal(1, b["v"])
|
481
|
+
end
|
482
|
+
|
483
|
+
def test_decode_body_raises_an_error_if_the_body_does_not_have_a_token
|
484
|
+
j = Jwt.new(secret: "***", algorithm: "HS256", claims: [])
|
485
|
+
|
486
|
+
assert_raise_with_message(KeyError, "Expected the body to have a 'token' key, but it did not") do
|
487
|
+
j.decode_body({})
|
488
|
+
end
|
489
|
+
end
|
490
|
+
|
491
|
+
def test_decode_body_raises_an_error_if_the_token_is_not_a_string
|
492
|
+
j = Jwt.new(secret: "***", algorithm: "HS256", claims: [])
|
493
|
+
|
494
|
+
assert_raise_with_message(TypeError, "Expected the 'token' key to be a String, but it was a Integer") do
|
495
|
+
j.decode_body({"token" => 1})
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
def test_decode_header_decodes
|
500
|
+
j = Jwt.new(secret: "***", algorithm: "HS256", claims: [])
|
501
|
+
|
502
|
+
h = j.encode_header("v")
|
503
|
+
|
504
|
+
h = j.decode_header(h)
|
505
|
+
assert_equal("v", h)
|
506
|
+
end
|
507
|
+
|
508
|
+
def test_decode_header_raises_an_error_if_the_header_does_not_have_a_payload
|
509
|
+
j = Jwt.new(secret: "***", algorithm: "HS256", claims: [])
|
510
|
+
|
511
|
+
h = encode(j, {"v" => 1})
|
512
|
+
|
513
|
+
assert_raise_with_message(KeyError, "Expected the decoded header to have a 'payload' key, but it did not") do
|
514
|
+
j.decode_header(h)
|
515
|
+
end
|
516
|
+
end
|
517
|
+
|
518
|
+
def test_decode_uri_decodes
|
519
|
+
j = Jwt.new(secret: "***", algorithm: "HS256", claims: [])
|
520
|
+
|
521
|
+
u = T.cast(URI.parse("http://localhost:8080/"), URI::HTTP)
|
522
|
+
n = j.encode_uri(u)
|
523
|
+
|
524
|
+
u = j.decode_uri(n)
|
525
|
+
assert_equal("http://localhost:8080/", u.to_s)
|
526
|
+
end
|
527
|
+
|
528
|
+
def test_decode_uri_raises_an_error_if_the_uri_does_not_have_a_query_string
|
529
|
+
j = Jwt.new(secret: "***", algorithm: "HS256", claims: [])
|
530
|
+
|
531
|
+
u = T.cast(URI.parse("http://localhost:8080/"), URI::HTTP)
|
532
|
+
|
533
|
+
assert_raise_with_message(ArgumentError, "Expected the URI to have a query string, but it did not") do
|
534
|
+
j.decode_uri(u)
|
535
|
+
end
|
536
|
+
end
|
537
|
+
|
538
|
+
def test_decode_uri_raises_an_error_if_the_query_string_does_not_have_a_token
|
539
|
+
j = Jwt.new(secret: "***", algorithm: "HS256", claims: [])
|
540
|
+
|
541
|
+
u = T.cast(URI.parse("http://localhost:8080/?v=1"), URI::HTTP)
|
542
|
+
|
543
|
+
assert_raise_with_message(KeyError, "Expected the query string to have a 'token' key, but it did not") do
|
544
|
+
j.decode_uri(u)
|
545
|
+
end
|
546
|
+
end
|
547
|
+
|
548
|
+
def test_decode_uri_raises_an_error_if_the_decoded_token_does_not_have_a_url
|
549
|
+
j = Jwt.new(secret: "***", algorithm: "HS256", claims: [])
|
550
|
+
|
551
|
+
u = T.cast(URI.parse("http://localhost:8080/"), URI::HTTP)
|
552
|
+
f = URI.decode_www_form("")
|
553
|
+
f.append(["token", j.encode({"v" => 1})])
|
554
|
+
u.query = URI.encode_www_form(f)
|
555
|
+
|
556
|
+
assert_raise_with_message(KeyError, "Expected the decoded token to have a 'url' key, but it did not") do
|
557
|
+
j.decode_uri(u)
|
558
|
+
end
|
559
|
+
end
|
560
|
+
|
561
|
+
def test_decode_uri_raises_an_error_if_the_url_is_not_a_string
|
562
|
+
j = Jwt.new(secret: "***", algorithm: "HS256", claims: [])
|
563
|
+
|
564
|
+
u = T.cast(URI.parse("http://localhost:8080/"), URI::HTTP)
|
565
|
+
f = URI.decode_www_form("")
|
566
|
+
f.append(["token", j.encode({"url" => 1})])
|
567
|
+
u.query = URI.encode_www_form(f)
|
568
|
+
|
569
|
+
assert_raise_with_message(TypeError, "Expected the 'url' key to be a String, but it was a Integer") do
|
570
|
+
j.decode_uri(u)
|
571
|
+
end
|
572
|
+
end
|
573
|
+
|
574
|
+
def test_decode_uri_raises_an_error_if_the_url_is_not_a_uri_http
|
575
|
+
j = Jwt.new(secret: "***", algorithm: "HS256", claims: [])
|
576
|
+
|
577
|
+
u = T.cast(URI.parse("http://localhost:8080/"), URI::HTTP)
|
578
|
+
f = URI.decode_www_form("")
|
579
|
+
f.append(["token", j.encode({"url" => "sftp://localhost:8080/"})])
|
580
|
+
u.query = URI.encode_www_form(f)
|
581
|
+
|
582
|
+
assert_raise_with_message(TypeError, "Expected the 'url' key to be a URI::HTTP, but it was a URI::Generic") do
|
583
|
+
j.decode_uri(u)
|
584
|
+
end
|
585
|
+
end
|
586
|
+
|
587
|
+
sig {params(j: Jwt, p: T.untyped).returns(T.untyped)}
|
588
|
+
def encode(j, p)
|
589
|
+
JWT.encode(p, j.secret, j.algorithm)
|
590
|
+
end
|
591
|
+
|
592
|
+
sig {params(j: Jwt, t: String).returns(T.untyped)}
|
593
|
+
def decode(j, t)
|
594
|
+
JWT.decode(t, j.secret, true, {algorithm: j.algorithm})
|
595
|
+
end
|
596
|
+
end
|
597
|
+
end
|
598
|
+
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
#
|
2
|
+
# (c) Copyright Ascensio System SIA 2025
|
3
|
+
#
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
# you may not use this file except in compliance with the License.
|
6
|
+
# You may obtain a copy of the License at
|
7
|
+
#
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
#
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
# See the License for the specific language governing permissions and
|
14
|
+
# limitations under the License.
|
15
|
+
#
|
16
|
+
|
17
|
+
# typed: strict
|
18
|
+
# frozen_string_literal: true
|
19
|
+
|
20
|
+
require "sorbet-runtime"
|
21
|
+
require "test/unit"
|
22
|
+
|
23
|
+
module Onlyoffice
|
24
|
+
module DocsIntegrationSdk
|
25
|
+
module Test
|
26
|
+
module BasicEnumMarshalling
|
27
|
+
extend T::Sig
|
28
|
+
extend T::Helpers
|
29
|
+
include ::Test::Unit::Assertions
|
30
|
+
abstract!
|
31
|
+
|
32
|
+
sig {abstract.returns(T::Array[[T.untyped, T::Enum]])}
|
33
|
+
def cases; end
|
34
|
+
|
35
|
+
sig {void}
|
36
|
+
def test_serialize_serializes
|
37
|
+
for v, c in cases
|
38
|
+
assert_equal(v, c.serialize)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
sig {void}
|
43
|
+
def test_from_serialized_deserializes
|
44
|
+
for v, c in cases
|
45
|
+
assert_equal(c, c.class.from_serialized(v))
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
module DescriptiveEnumMarshalling
|
51
|
+
extend T::Sig
|
52
|
+
extend T::Helpers
|
53
|
+
include ::Test::Unit::Assertions
|
54
|
+
abstract!
|
55
|
+
|
56
|
+
sig {abstract.returns(T::Array[[T.untyped, String, T::Enum]])}
|
57
|
+
def cases; end
|
58
|
+
|
59
|
+
sig {void}
|
60
|
+
def test_serialize_serializes
|
61
|
+
for v, _, c in cases
|
62
|
+
assert_equal(v, c.serialize)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
sig {void}
|
67
|
+
def test_from_serialized_deserializes
|
68
|
+
for v, _, c in cases
|
69
|
+
assert_equal(c, c.class.from_serialized(v))
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
sig {void}
|
74
|
+
def test_description_returns_the_description
|
75
|
+
for _, d, c in cases
|
76
|
+
m = c.method(:description)
|
77
|
+
assert_equal(d, m.call)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
module StructMarshalling
|
83
|
+
extend T::Sig
|
84
|
+
extend T::Helpers
|
85
|
+
include ::Test::Unit::Assertions
|
86
|
+
abstract!
|
87
|
+
|
88
|
+
sig {abstract.returns(T::Array[[T.untyped, T::Struct]])}
|
89
|
+
def cases; end
|
90
|
+
|
91
|
+
sig {void}
|
92
|
+
def test_serialize_serializes
|
93
|
+
for v, c in cases
|
94
|
+
assert_equal(v, c.serialize)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
sig {void}
|
99
|
+
def test_from_hash_deserializes
|
100
|
+
for v, c in cases
|
101
|
+
m = c.class.method(:from_hash)
|
102
|
+
|
103
|
+
t = T::Private::Methods.signature_for_method(m)
|
104
|
+
assert_equal(t.return_type.raw_type, c.class)
|
105
|
+
|
106
|
+
s = m.call(v)
|
107
|
+
# todo: assert_equal(c, s)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|