20318: Implement BlockRead via ReadAt so it supports streaming.
[arvados.git] / services / api / test / unit / blob_test.rb
1 # Copyright (C) The Arvados Authors. All rights reserved.
2 #
3 # SPDX-License-Identifier: AGPL-3.0
4
5 require 'test_helper'
6
7 class BlobTest < ActiveSupport::TestCase
8   @@api_token = rand(2**512).to_s(36)[0..49]
9   @@key = rand(2**2048).to_s(36)
10   @@blob_data = 'foo'
11   @@blob_locator = Digest::MD5.hexdigest(@@blob_data) +
12     '+' + @@blob_data.size.to_s
13
14   @@known_locator = 'acbd18db4cc2f85cedef654fccc4a4d8+3'
15   @@known_token = 'hocfupkn2pjhrpgp2vxv8rsku7tvtx49arbc9s4bvu7p7wxqvk'
16   @@known_key = '13u9fkuccnboeewr0ne3mvapk28epf68a3bhj9q8sb4l6e4e5mkk' +
17     'p6nhj2mmpscgu1zze5h5enydxfe3j215024u16ij4hjaiqs5u4pzsl3nczmaoxnc' +
18     'ljkm4875xqn4xv058koz3vkptmzhyheiy6wzevzjmdvxhvcqsvr5abhl15c2d4o4' +
19     'jhl0s91lojy1mtrzqqvprqcverls0xvy9vai9t1l1lvvazpuadafm71jl4mrwq2y' +
20     'gokee3eamvjy8qq1fvy238838enjmy5wzy2md7yvsitp5vztft6j4q866efym7e6' +
21     'vu5wm9fpnwjyxfldw3vbo01mgjs75rgo7qioh8z8ij7jpyp8508okhgbbex3ceei' +
22     '786u5rw2a9gx743dj3fgq2irk'
23   @@known_signed_locator = 'acbd18db4cc2f85cedef654fccc4a4d8+3' +
24     '+A89118b78732c33104a4d6231e8b5a5fa1e4301e3@7fffffff'
25
26   test 'generate predictable invincible signature' do
27     signed = Blob.sign_locator @@known_locator, {
28       api_token: @@known_token,
29       key: @@known_key,
30       expire: 0x7fffffff,
31     }
32     assert_equal @@known_signed_locator, signed
33   end
34
35   test 'verify predictable invincible signature' do
36     assert_equal true, Blob.verify_signature!(@@known_signed_locator,
37                                               api_token: @@known_token,
38                                               key: @@known_key)
39   end
40
41   test 'correct' do
42     signed = Blob.sign_locator @@blob_locator, api_token: @@api_token, key: @@key
43     assert_equal true, Blob.verify_signature!(signed, api_token: @@api_token, key: @@key)
44   end
45
46   test 'expired' do
47     signed = Blob.sign_locator @@blob_locator, api_token: @@api_token, key: @@key, ttl: -1
48     assert_raise Blob::InvalidSignatureError do
49       Blob.verify_signature!(signed, api_token: @@api_token, key: @@key)
50     end
51   end
52
53   test 'expired, but no raise' do
54     signed = Blob.sign_locator @@blob_locator, api_token: @@api_token, key: @@key, ttl: -1
55     assert_equal false, Blob.verify_signature(signed,
56                                               api_token: @@api_token,
57                                               key: @@key)
58   end
59
60   test 'bogus, wrong block hash' do
61     signed = Blob.sign_locator @@blob_locator, api_token: @@api_token, key: @@key
62     assert_raise Blob::InvalidSignatureError do
63       Blob.verify_signature!(signed.sub('acbd','abcd'), api_token: @@api_token, key: @@key)
64     end
65   end
66
67   test 'bogus, expired' do
68     signed = 'acbd18db4cc2f85cedef654fccc4a4d8+3+Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@531641bf'
69     assert_raises Blob::InvalidSignatureError do
70       Blob.verify_signature!(signed, api_token: @@api_token, key: @@key)
71     end
72   end
73
74   test 'bogus, wrong key' do
75     signed = Blob.sign_locator(@@blob_locator,
76                                api_token: @@api_token,
77                                key: (@@key+'x'))
78     assert_raise Blob::InvalidSignatureError do
79       Blob.verify_signature!(signed, api_token: @@api_token, key: @@key)
80     end
81   end
82
83   test 'bogus, wrong api token' do
84     signed = Blob.sign_locator(@@blob_locator,
85                                api_token: @@api_token.reverse,
86                                key: @@key)
87     assert_raise Blob::InvalidSignatureError do
88       Blob.verify_signature!(signed, api_token: @@api_token, key: @@key)
89     end
90   end
91
92   test 'bogus, signature format 1' do
93     signed = 'acbd18db4cc2f85cedef654fccc4a4d8+3+Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@'
94     assert_raise Blob::InvalidSignatureError do
95       Blob.verify_signature!(signed, api_token: @@api_token, key: @@key)
96     end
97   end
98
99   test 'bogus, signature format 2' do
100     signed = 'acbd18db4cc2f85cedef654fccc4a4d8+3+A@531641bf'
101     assert_raise Blob::InvalidSignatureError do
102       Blob.verify_signature!(signed, api_token: @@api_token, key: @@key)
103     end
104   end
105
106   test 'bogus, signature format 3' do
107     signed = 'acbd18db4cc2f85cedef654fccc4a4d8+3+Axyzzy@531641bf'
108     assert_raise Blob::InvalidSignatureError do
109       Blob.verify_signature!(signed, api_token: @@api_token, key: @@key)
110     end
111   end
112
113   test 'bogus, timestamp format' do
114     signed = 'acbd18db4cc2f85cedef654fccc4a4d8+3+Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa@xyzzy'
115     assert_raise Blob::InvalidSignatureError do
116       Blob.verify_signature!(signed, api_token: @@api_token, key: @@key)
117     end
118   end
119
120   test 'no signature at all' do
121     assert_raise Blob::InvalidSignatureError do
122       Blob.verify_signature!(@@blob_locator, api_token: @@api_token, key: @@key)
123     end
124   end
125
126   test 'signature changes when ttl changes' do
127     signed = Blob.sign_locator @@known_locator, {
128       api_token: @@known_token,
129       key: @@known_key,
130       expire: 0x7fffffff,
131     }
132
133     original_ttl = Rails.configuration.Collections.BlobSigningTTL
134     Rails.configuration.Collections.BlobSigningTTL = original_ttl*2
135     signed2 = Blob.sign_locator @@known_locator, {
136       api_token: @@known_token,
137       key: @@known_key,
138       expire: 0x7fffffff,
139     }
140     Rails.configuration.Collections.BlobSigningTTL = original_ttl
141
142     assert_not_equal signed, signed2
143   end
144 end