drillbit 2.11.0 → 3.0.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/drillbit.rb +1 -0
- data/lib/drillbit/accept_header.rb +1 -0
- data/lib/drillbit/authorizable_resource.rb +61 -60
- data/lib/drillbit/authorizers/parameters.rb +1 -0
- data/lib/drillbit/authorizers/parameters/filtering.rb +7 -6
- data/lib/drillbit/authorizers/parameters/inclusions.rb +6 -9
- data/lib/drillbit/authorizers/parameters/resource.rb +20 -19
- data/lib/drillbit/authorizers/query.rb +1 -0
- data/lib/drillbit/authorizers/scope.rb +5 -4
- data/lib/drillbit/compatibility/controllers.rb +1 -0
- data/lib/drillbit/configuration.rb +14 -16
- data/lib/drillbit/errors/invalid_api_request.rb +1 -0
- data/lib/drillbit/errors/invalid_request_body.rb +1 -0
- data/lib/drillbit/errors/invalid_subdomain.rb +1 -0
- data/lib/drillbit/errors/invalid_token.rb +1 -0
- data/lib/drillbit/errors/unpermitted_inclusions.rb +1 -0
- data/lib/drillbit/matchers/accept_header.rb +1 -0
- data/lib/drillbit/matchers/generic.rb +4 -3
- data/lib/drillbit/matchers/subdomain.rb +5 -6
- data/lib/drillbit/matchers/version.rb +3 -2
- data/lib/drillbit/middleware/api_request_validator.rb +4 -3
- data/lib/drillbit/middleware/parameter_parser.rb +1 -0
- data/lib/drillbit/middleware/token_processor.rb +1 -0
- data/lib/drillbit/parameters/filter.rb +12 -11
- data/lib/drillbit/parameters/index.rb +3 -2
- data/lib/drillbit/parameters/page.rb +1 -0
- data/lib/drillbit/parameters/sort.rb +1 -0
- data/lib/drillbit/requests/base.rb +1 -1
- data/lib/drillbit/requests/rack.rb +3 -0
- data/lib/drillbit/requests/rails.rb +1 -0
- data/lib/drillbit/resource.rb +1 -0
- data/lib/drillbit/resource/model.rb +5 -4
- data/lib/drillbit/resource/naming.rb +11 -10
- data/lib/drillbit/resource/processors/filtering.rb +1 -0
- data/lib/drillbit/resource/processors/indexing.rb +1 -0
- data/lib/drillbit/resource/processors/paging.rb +4 -3
- data/lib/drillbit/resource/processors/sorting.rb +1 -0
- data/lib/drillbit/responses/invalid_api_request.rb +3 -0
- data/lib/drillbit/responses/invalid_request_body.rb +3 -0
- data/lib/drillbit/responses/invalid_subdomain.rb +3 -0
- data/lib/drillbit/responses/invalid_token.rb +3 -0
- data/lib/drillbit/serializers/json_api.rb +12 -11
- data/lib/drillbit/tokens/base64.rb +1 -0
- data/lib/drillbit/tokens/base64s/invalid.rb +1 -0
- data/lib/drillbit/tokens/base64s/null.rb +1 -0
- data/lib/drillbit/tokens/invalid.rb +1 -0
- data/lib/drillbit/tokens/json_web_token.rb +6 -5
- data/lib/drillbit/tokens/json_web_tokens/invalid.rb +1 -0
- data/lib/drillbit/tokens/json_web_tokens/null.rb +1 -0
- data/lib/drillbit/tokens/json_web_tokens/password_reset.rb +1 -0
- data/lib/drillbit/tokens/null.rb +1 -0
- data/lib/drillbit/utilities/string.rb +1 -0
- data/lib/drillbit/version.rb +2 -1
- metadata +28 -94
- metadata.gz.sig +0 -0
- data/Rakefile +0 -2
- data/spec/drillbit/accept_header_spec.rb +0 -119
- data/spec/drillbit/authorizers/parameters/filtering_spec.rb +0 -101
- data/spec/drillbit/authorizers/parameters/resource_spec.rb +0 -12
- data/spec/drillbit/authorizers/parameters_spec.rb +0 -19
- data/spec/drillbit/authorizers/query_spec.rb +0 -24
- data/spec/drillbit/authorizers/scope_spec.rb +0 -21
- data/spec/drillbit/errors/invalid_api_request_spec.rb +0 -31
- data/spec/drillbit/errors/invalid_request_body_spec.rb +0 -25
- data/spec/drillbit/errors/invalid_subdomain_spec.rb +0 -30
- data/spec/drillbit/errors/invalid_token_spec.rb +0 -24
- data/spec/drillbit/invalid_subdomain_spec.rb +0 -45
- data/spec/drillbit/invalid_token_spec.rb +0 -44
- data/spec/drillbit/matchers/accept_header_spec.rb +0 -114
- data/spec/drillbit/matchers/subdomain_spec.rb +0 -78
- data/spec/drillbit/matchers/version_spec.rb +0 -86
- data/spec/drillbit/middleware/api_request_validator_spec.rb +0 -185
- data/spec/drillbit/middleware/parameter_parser_spec.rb +0 -200
- data/spec/drillbit/middleware/token_processor_spec.rb +0 -27
- data/spec/drillbit/requests/base_spec.rb +0 -37
- data/spec/drillbit/requests/rack_spec.rb +0 -252
- data/spec/drillbit/requests/rails_spec.rb +0 -264
- data/spec/drillbit/resource/model_spec.rb +0 -64
- data/spec/drillbit/resource/processors/filtering_spec.rb +0 -106
- data/spec/drillbit/resource/processors/indexing_spec.rb +0 -45
- data/spec/drillbit/resource/processors/paging_spec.rb +0 -74
- data/spec/drillbit/resource/processors/sorting_spec.rb +0 -66
- data/spec/drillbit/tokens/base64_spec.rb +0 -44
- data/spec/drillbit/tokens/json_web_token_spec.rb +0 -231
- data/spec/drillbit/tokens/json_web_tokens/password_reset_spec.rb +0 -43
- data/spec/fixtures/test_rsa_key +0 -27
- data/spec/fixtures/test_rsa_key.pub +0 -9
- data/spec/spec_helper.rb +0 -4
- data/spec/support/private_keys.rb +0 -42
@@ -1,64 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'rspeckled/spec_helpers/rspeckled'
|
3
|
-
require 'drillbit/resource/model'
|
4
|
-
|
5
|
-
module Drillbit
|
6
|
-
module Resource
|
7
|
-
describe Model do
|
8
|
-
it 'can chain multiple processors together' do
|
9
|
-
resource = double
|
10
|
-
processed_resource = double
|
11
|
-
|
12
|
-
model = Model.new(resource: resource,
|
13
|
-
parameters: {
|
14
|
-
'filter' => {
|
15
|
-
'query' => 'my_query',
|
16
|
-
'single_arity' => true,
|
17
|
-
'multiple_arity' => 'multi',
|
18
|
-
},
|
19
|
-
'sort' => 'my_attribute',
|
20
|
-
'page' => {
|
21
|
-
'number' => 10,
|
22
|
-
'size' => 100,
|
23
|
-
},
|
24
|
-
})
|
25
|
-
|
26
|
-
allow(resource).to receive(:single_arity).
|
27
|
-
and_return(resource)
|
28
|
-
allow(resource).to receive(:multiple_arity).
|
29
|
-
with('multi').
|
30
|
-
and_return(resource)
|
31
|
-
allow(resource).to receive(:order).
|
32
|
-
with('my_attribute' => 'asc').
|
33
|
-
and_return(resource)
|
34
|
-
allow(resource).to receive(:page).
|
35
|
-
with(10).
|
36
|
-
and_return(resource)
|
37
|
-
allow(resource).to receive(:per).
|
38
|
-
with(100).
|
39
|
-
and_return(resource)
|
40
|
-
allow(resource).to receive(:for_query).
|
41
|
-
with('my_query').
|
42
|
-
and_return(processed_resource)
|
43
|
-
|
44
|
-
allow(processed_resource).to receive(:total_pages).
|
45
|
-
and_return(10)
|
46
|
-
allow(processed_resource).to receive(:current_page).
|
47
|
-
and_return(5)
|
48
|
-
allow(processed_resource).to receive(:prev_page).
|
49
|
-
and_return(4)
|
50
|
-
allow(processed_resource).to receive(:next_page).
|
51
|
-
and_return(6)
|
52
|
-
|
53
|
-
expect(model.processed).to eql processed_resource
|
54
|
-
expect(model.meta).to eql(
|
55
|
-
'current-page' => 5,
|
56
|
-
'total-pages' => 10,
|
57
|
-
'previous-page' => 4,
|
58
|
-
'next-page' => 6,
|
59
|
-
'sort' => { 'my_attribute' => 'asc' },
|
60
|
-
)
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
@@ -1,106 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'rspeckled/spec_helpers/rspeckled'
|
3
|
-
require 'drillbit/resource/processors/filtering'
|
4
|
-
|
5
|
-
module Drillbit
|
6
|
-
module Resource
|
7
|
-
module Processors
|
8
|
-
describe Filtering do
|
9
|
-
let(:filtering_resource) { double }
|
10
|
-
|
11
|
-
it 'can return the resource if not filtered parameters are passed in' do
|
12
|
-
filtering = Filtering.new(filtering_resource)
|
13
|
-
|
14
|
-
expect(filtering.processed).to eql filtering_resource
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'can return a queried resource' do
|
18
|
-
filtering = Filtering.new(filtering_resource,
|
19
|
-
'filter' => {
|
20
|
-
'stuff' => 'blah',
|
21
|
-
})
|
22
|
-
|
23
|
-
allow(filtering_resource).to receive(:for_stuff).
|
24
|
-
with('blah').
|
25
|
-
and_return 'stuffed'
|
26
|
-
|
27
|
-
expect(filtering.processed).to eql 'stuffed'
|
28
|
-
end
|
29
|
-
|
30
|
-
it 'does not try to query if the resource cannot query for that thing' do
|
31
|
-
filtering = Filtering.new(filtering_resource,
|
32
|
-
'filter' => {
|
33
|
-
'whatever' => 'blah',
|
34
|
-
})
|
35
|
-
|
36
|
-
expect(filtering.processed).to eql filtering_resource
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'can query for something that does not take arguments' do
|
40
|
-
filtering = Filtering.new(filtering_resource,
|
41
|
-
'filter' => {
|
42
|
-
'stuff' => 'blah',
|
43
|
-
})
|
44
|
-
|
45
|
-
allow(filtering_resource).to receive(:stuff).
|
46
|
-
and_return 'stuffed'
|
47
|
-
|
48
|
-
expect(filtering.processed).to eql 'stuffed'
|
49
|
-
end
|
50
|
-
|
51
|
-
it 'can query for something that does not take arguments' do
|
52
|
-
filtering = Filtering.new(filtering_resource,
|
53
|
-
'filter' => {
|
54
|
-
'stuff' => 'blah',
|
55
|
-
'other_stuff' => 'other_blah',
|
56
|
-
})
|
57
|
-
|
58
|
-
allow(filtering_resource).to receive(:for_stuff).
|
59
|
-
with('blah').
|
60
|
-
and_return filtering_resource
|
61
|
-
allow(filtering_resource).to receive(:other_stuff).
|
62
|
-
and_return 'other_stuffed'
|
63
|
-
|
64
|
-
expect(filtering.processed).to eql 'other_stuffed'
|
65
|
-
end
|
66
|
-
|
67
|
-
it 'can properly format numerical ranges' do
|
68
|
-
filtering = Filtering.new(filtering_resource,
|
69
|
-
'filter' => {
|
70
|
-
'stuff' => '100...200',
|
71
|
-
'infinity' => '9...Infinity',
|
72
|
-
'other_stuff' => '3_333.33..8_8__8.0',
|
73
|
-
})
|
74
|
-
|
75
|
-
allow(filtering_resource).to receive(:for_stuff).
|
76
|
-
with(100.0...200.0).
|
77
|
-
and_return filtering_resource
|
78
|
-
allow(filtering_resource).to receive(:infinity).
|
79
|
-
with(9.0...9_999_999).
|
80
|
-
and_return filtering_resource
|
81
|
-
allow(filtering_resource).to receive(:other_stuff).
|
82
|
-
with(3333.33..888.0).
|
83
|
-
and_return 'other_stuffed'
|
84
|
-
|
85
|
-
expect(filtering.processed).to eql 'other_stuffed'
|
86
|
-
end
|
87
|
-
|
88
|
-
it 'can handle objects (eg ActiveRelation) that store their proxy class in klass' do
|
89
|
-
resource_class = double
|
90
|
-
filtering = Filtering.new(filtering_resource,
|
91
|
-
'filter' => {
|
92
|
-
'stuff' => 'blah',
|
93
|
-
})
|
94
|
-
|
95
|
-
allow(filtering_resource).to receive(:klass).
|
96
|
-
and_return(resource_class)
|
97
|
-
allow(resource_class).to receive(:stuff)
|
98
|
-
allow(filtering_resource).to receive(:stuff).
|
99
|
-
and_return 'stuffed'
|
100
|
-
|
101
|
-
expect(filtering.processed).to eql 'stuffed'
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'rspeckled/spec_helpers/rspeckled'
|
3
|
-
require 'drillbit/resource/processors/indexing'
|
4
|
-
|
5
|
-
module Drillbit
|
6
|
-
class TestIndexClass
|
7
|
-
def for_query(_param); end
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
module Drillbit
|
12
|
-
module Resource
|
13
|
-
module Processors
|
14
|
-
describe Indexing do
|
15
|
-
let(:indexing_resource) { double }
|
16
|
-
|
17
|
-
it 'does not do anything if indexing params are not passed in' do
|
18
|
-
indexing = Indexing.new(indexing_resource)
|
19
|
-
|
20
|
-
expect(indexing.processed).to eql indexing_resource
|
21
|
-
end
|
22
|
-
|
23
|
-
it 'does not do anything if indexing params are passed in but they are blank' do
|
24
|
-
indexing = Indexing.new(indexing_resource,
|
25
|
-
'filter' => {
|
26
|
-
'query' => '',
|
27
|
-
})
|
28
|
-
|
29
|
-
expect(indexing.processed).to eql indexing_resource
|
30
|
-
end
|
31
|
-
|
32
|
-
it 'forces a query even if no parameters were passed in' do
|
33
|
-
indexing_resource = TestIndexClass.new
|
34
|
-
indexing = Indexing.new(indexing_resource)
|
35
|
-
|
36
|
-
allow(indexing_resource).to receive(:for_query).
|
37
|
-
with('*').
|
38
|
-
and_return('blah')
|
39
|
-
|
40
|
-
expect(indexing.processed).to eql 'blah'
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
@@ -1,74 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'rspeckled/spec_helpers/rspeckled'
|
3
|
-
require 'drillbit/resource/processors/paging'
|
4
|
-
|
5
|
-
module Drillbit
|
6
|
-
module Resource
|
7
|
-
module Processors
|
8
|
-
describe Paging do
|
9
|
-
let(:paging_resource) { double }
|
10
|
-
let(:processed_resource) { double }
|
11
|
-
|
12
|
-
it 'can return a default page' do
|
13
|
-
paging = Paging.new(paging_resource,
|
14
|
-
'page' => {
|
15
|
-
'size' => 10,
|
16
|
-
})
|
17
|
-
|
18
|
-
allow(paging_resource).to receive(:total_pages).and_return 10
|
19
|
-
allow(paging_resource).to receive(:current_page).and_return 1
|
20
|
-
allow(paging_resource).to receive(:prev_page).and_return nil
|
21
|
-
allow(paging_resource).to receive(:next_page).and_return nil
|
22
|
-
|
23
|
-
allow(paging_resource).to receive(:page).
|
24
|
-
with(1).
|
25
|
-
and_return paging_resource
|
26
|
-
allow(paging_resource).to receive(:per).
|
27
|
-
with(10).
|
28
|
-
and_return processed_resource
|
29
|
-
|
30
|
-
expect(paging.processed).to eql processed_resource
|
31
|
-
expect(paging.meta).to eql(
|
32
|
-
'total-pages' => 10,
|
33
|
-
'current-page' => 1,
|
34
|
-
'previous-page' => nil,
|
35
|
-
'next-page' => nil,
|
36
|
-
)
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'can return a pageed resource' do
|
40
|
-
paging = Paging.new(paging_resource,
|
41
|
-
'page' => {
|
42
|
-
'number' => 5,
|
43
|
-
'size' => 10,
|
44
|
-
})
|
45
|
-
|
46
|
-
allow(paging_resource).to receive(:page).
|
47
|
-
with(5).
|
48
|
-
and_return paging_resource
|
49
|
-
allow(paging_resource).to receive(:per).
|
50
|
-
with(10).
|
51
|
-
and_return processed_resource
|
52
|
-
|
53
|
-
expect(paging.processed).to eql processed_resource
|
54
|
-
end
|
55
|
-
|
56
|
-
it 'does not consider non-ideomatic page params as valid' do
|
57
|
-
paging = Paging.new(paging_resource,
|
58
|
-
'page' => {
|
59
|
-
'nombre' => 5,
|
60
|
-
'tamano' => 10,
|
61
|
-
})
|
62
|
-
|
63
|
-
expect(paging.processed).to eql paging_resource
|
64
|
-
end
|
65
|
-
|
66
|
-
it 'does not do anything if page params are not passed in' do
|
67
|
-
paging = Paging.new(paging_resource)
|
68
|
-
|
69
|
-
expect(paging.processed).to eql paging_resource
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
@@ -1,66 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'rspeckled/spec_helpers/rspeckled'
|
3
|
-
require 'drillbit/resource/processors/sorting'
|
4
|
-
|
5
|
-
module Drillbit
|
6
|
-
module Resource
|
7
|
-
module Processors
|
8
|
-
describe Sorting do
|
9
|
-
let(:sorting_resource) { double }
|
10
|
-
|
11
|
-
it 'can return an ascending sort' do
|
12
|
-
sorting = Sorting.new(sorting_resource, 'sort' => 'my_attribute')
|
13
|
-
|
14
|
-
allow(sorting_resource).to receive(:order).
|
15
|
-
with('my_attribute' => 'asc').
|
16
|
-
and_return('sorted')
|
17
|
-
|
18
|
-
expect(sorting.processed).to eql 'sorted'
|
19
|
-
expect(sorting.meta).to eql(
|
20
|
-
'sort' => {
|
21
|
-
'my_attribute' => 'asc',
|
22
|
-
},
|
23
|
-
)
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'can return a descending sort' do
|
27
|
-
sorting = Sorting.new(sorting_resource, 'sort' => '-my_attribute')
|
28
|
-
|
29
|
-
allow(sorting_resource).to receive(:order).
|
30
|
-
with('my_attribute' => 'desc').
|
31
|
-
and_return('sorted')
|
32
|
-
|
33
|
-
expect(sorting.processed).to eql 'sorted'
|
34
|
-
expect(sorting.meta).to eql(
|
35
|
-
'sort' => {
|
36
|
-
'my_attribute' => 'desc',
|
37
|
-
},
|
38
|
-
)
|
39
|
-
end
|
40
|
-
|
41
|
-
it 'can return multiple sorts' do
|
42
|
-
sorting = Sorting.new(sorting_resource, 'sort' => '-my_attribute,my_other_attribute')
|
43
|
-
|
44
|
-
allow(sorting_resource).to receive(:order).
|
45
|
-
with('my_attribute' => 'desc',
|
46
|
-
'my_other_attribute' => 'asc').
|
47
|
-
and_return('sorted')
|
48
|
-
|
49
|
-
expect(sorting.processed).to eql 'sorted'
|
50
|
-
expect(sorting.meta).to eql(
|
51
|
-
'sort' => {
|
52
|
-
'my_attribute' => 'desc',
|
53
|
-
'my_other_attribute' => 'asc',
|
54
|
-
},
|
55
|
-
)
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'does not do anything if sorting params are not passed in' do
|
59
|
-
sorting = Sorting.new(sorting_resource)
|
60
|
-
|
61
|
-
expect(sorting.processed).to eql sorting_resource
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
@@ -1,44 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'rspeckled/spec_helpers/rspeckled'
|
3
|
-
require 'drillbit/tokens/base64'
|
4
|
-
|
5
|
-
module Drillbit
|
6
|
-
module Tokens
|
7
|
-
describe Base64 do
|
8
|
-
it 'is valid' do
|
9
|
-
expect(Base64.new(token: 'foo')).to be_valid
|
10
|
-
end
|
11
|
-
|
12
|
-
it 'is not blank' do
|
13
|
-
expect(Base64.new(token: 'foo')).not_to be_blank
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'can convert itself into a hash' do
|
17
|
-
token = Base64.new(token: 'foo')
|
18
|
-
|
19
|
-
expect(token.to_h).to eql([
|
20
|
-
{
|
21
|
-
'token' => 'foo',
|
22
|
-
},
|
23
|
-
{
|
24
|
-
'typ' => 'base64',
|
25
|
-
},
|
26
|
-
])
|
27
|
-
end
|
28
|
-
|
29
|
-
it 'can convert itself into a null token' do
|
30
|
-
token = Base64.convert(raw_token: nil)
|
31
|
-
|
32
|
-
expect(token).to be_valid
|
33
|
-
expect(token).to be_blank
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'can convert itself into an invalid token' do
|
37
|
-
token = Base64.convert(raw_token: 'bla.h')
|
38
|
-
|
39
|
-
expect(token).not_to be_valid
|
40
|
-
expect(token).not_to be_blank
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
@@ -1,231 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'rspeckled/spec_helpers/rspeckled'
|
3
|
-
require 'drillbit/tokens/json_web_token'
|
4
|
-
|
5
|
-
module Drillbit
|
6
|
-
module Tokens
|
7
|
-
describe JsonWebToken do
|
8
|
-
it 'can convert an empty encrypted token' do
|
9
|
-
token = JsonWebToken.from_jwe(nil,
|
10
|
-
private_key: test_private_key)
|
11
|
-
|
12
|
-
expect(token).to be_a JsonWebTokens::Null
|
13
|
-
end
|
14
|
-
|
15
|
-
it 'can convert an invalid encrypted token' do
|
16
|
-
token = JsonWebToken.from_jwe(invalid_jwe_token,
|
17
|
-
private_key: test_private_key)
|
18
|
-
|
19
|
-
expect(token).to be_a JsonWebTokens::Invalid
|
20
|
-
end
|
21
|
-
|
22
|
-
it 'can verify an expired encrypted token' do
|
23
|
-
expired_jwe = valid_jwe_token('exp' => 1.day.ago.to_i,
|
24
|
-
'baz' => 'bar')
|
25
|
-
token = JsonWebToken.from_jwe(expired_jwe,
|
26
|
-
private_key: test_private_key)
|
27
|
-
|
28
|
-
expect(token).to be_a JsonWebTokens::Invalid
|
29
|
-
end
|
30
|
-
|
31
|
-
it 'can convert an invalidly signed encrypted token' do
|
32
|
-
other_private_key = OpenSSL::PKey::RSA.new(2048)
|
33
|
-
token = JsonWebToken.from_jwe(valid_jwe_token,
|
34
|
-
private_key: other_private_key)
|
35
|
-
|
36
|
-
expect(token).to be_a JsonWebTokens::Invalid
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'can convert a valid encrypted token' do
|
40
|
-
token = JsonWebToken.from_jwe(valid_jwe_token,
|
41
|
-
private_key: test_private_key)
|
42
|
-
|
43
|
-
expect(token).to be_a JsonWebToken
|
44
|
-
expect(token.to_h).to eql(
|
45
|
-
[
|
46
|
-
{
|
47
|
-
'bar' => 'baz',
|
48
|
-
},
|
49
|
-
{
|
50
|
-
'typ' => 'JWT',
|
51
|
-
'alg' => 'RS256',
|
52
|
-
},
|
53
|
-
],
|
54
|
-
)
|
55
|
-
end
|
56
|
-
|
57
|
-
it 'can convert an empty signed token' do
|
58
|
-
token = JsonWebToken.from_jws(nil,
|
59
|
-
private_key: test_private_key)
|
60
|
-
|
61
|
-
expect(token).to be_a JsonWebTokens::Null
|
62
|
-
end
|
63
|
-
|
64
|
-
it 'can convert a token with no data' do
|
65
|
-
token = JsonWebToken.build_from_request([{}, {}])
|
66
|
-
|
67
|
-
expect(token).to be_empty
|
68
|
-
expect(token).not_to be_present
|
69
|
-
expect(token).to be_blank
|
70
|
-
end
|
71
|
-
|
72
|
-
it 'can verify an expired signed token' do
|
73
|
-
expired_jws = valid_jws_token('exp' => 1.day.ago.to_i,
|
74
|
-
'baz' => 'bar')
|
75
|
-
token = JsonWebToken.from_jws(expired_jws,
|
76
|
-
private_key: test_private_key)
|
77
|
-
|
78
|
-
expect(token).to be_a JsonWebTokens::Invalid
|
79
|
-
end
|
80
|
-
|
81
|
-
it 'can convert an invalidly signed token' do
|
82
|
-
other_private_key = OpenSSL::PKey::RSA.new(2048)
|
83
|
-
token_signed_with_another_key = JsonWebToken.from_jws(valid_jws_token,
|
84
|
-
private_key: other_private_key)
|
85
|
-
invalid_token = JsonWebToken.from_jws(invalid_jws_token,
|
86
|
-
private_key: test_private_key)
|
87
|
-
|
88
|
-
expect(token_signed_with_another_key).to be_a JsonWebTokens::Invalid
|
89
|
-
expect(invalid_token).to be_a JsonWebTokens::Invalid
|
90
|
-
end
|
91
|
-
|
92
|
-
it 'can convert a valid signed token' do
|
93
|
-
token = JsonWebToken.from_jws(valid_jws_token,
|
94
|
-
private_key: test_private_key)
|
95
|
-
|
96
|
-
expect(token).to be_a JsonWebToken
|
97
|
-
expect(token.to_h).to eql([{ 'bar' => 'baz' }, { 'typ' => 'JWT', 'alg' => 'RS256' }])
|
98
|
-
end
|
99
|
-
|
100
|
-
it 'can transform into a JWT' do
|
101
|
-
token = JsonWebToken.new(data: { 'foo' => 'bar' },
|
102
|
-
private_key: test_private_key)
|
103
|
-
|
104
|
-
jwt = token.to_jwt
|
105
|
-
jwt_s = token.to_jwt_s
|
106
|
-
|
107
|
-
expect(jwt.to_h).to eql('foo' => 'bar')
|
108
|
-
expect(jwt_s).to eql('eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJmb28iOiJiYXIifQ.')
|
109
|
-
end
|
110
|
-
|
111
|
-
# rubocop:disable Metrics/LineLength
|
112
|
-
it 'can transform into a JWS and back' do
|
113
|
-
token = JsonWebToken.new(data: { 'foo' => 'bar' },
|
114
|
-
private_key: test_private_key)
|
115
|
-
|
116
|
-
jws = token.to_jws
|
117
|
-
jws_s = token.to_jws_s
|
118
|
-
|
119
|
-
expect(jws.to_h).to eql('foo' => 'bar')
|
120
|
-
expect(jws_s).to eql('eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.DhPBu9Bfha08hSoy1a8Ps5YGxv2_KJCoNALH8dzd8b_VgKCPRQlIaHZwQfS5N1yfZczc2EqXIhPma4I2i-L92oDxyugZYfhMH6XUXSgB6F7SU5WtiglQ8gfgxC_u_K5htD_6zpRaHi6UTNbG8NF3RFBYK9za4GFPPWQawRQpdH2CxjyZP6pilmkynLuKx0OeQbJf1yzdgn1cDt60M8uoZZTzPgoU598ilDjYEETwyGyCi79S3A3ix8oDaJLhM8stPOHLUeglKrkwxOFglzVs7bULjzxZlygZujsHfWu16cjp_P3b4TIH_hiH0-Cjin-EVt4va2TnfGJ8HDxHxzWn7g')
|
121
|
-
|
122
|
-
converted_token = JsonWebToken.from_jws(jws_s,
|
123
|
-
private_key: test_private_key)
|
124
|
-
|
125
|
-
expect(converted_token.to_h).to eql [
|
126
|
-
{ 'foo' => 'bar' },
|
127
|
-
{ 'typ' => 'JWT', 'alg' => 'RS256' },
|
128
|
-
]
|
129
|
-
end
|
130
|
-
# rubocop:enable Metrics/LineLength
|
131
|
-
|
132
|
-
# rubocop:disable Metrics/LineLength
|
133
|
-
it 'can transform into a JWE and back' do
|
134
|
-
token = JsonWebToken.new(data: { 'foo' => 'bar' },
|
135
|
-
private_key: test_private_key)
|
136
|
-
|
137
|
-
jwe = token.to_jwe
|
138
|
-
jwe_s = token.to_jwe_s
|
139
|
-
|
140
|
-
expect(jwe.plain_text).to eql('eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJmb28iOiJiYXIifQ.DhPBu9Bfha08hSoy1a8Ps5YGxv2_KJCoNALH8dzd8b_VgKCPRQlIaHZwQfS5N1yfZczc2EqXIhPma4I2i-L92oDxyugZYfhMH6XUXSgB6F7SU5WtiglQ8gfgxC_u_K5htD_6zpRaHi6UTNbG8NF3RFBYK9za4GFPPWQawRQpdH2CxjyZP6pilmkynLuKx0OeQbJf1yzdgn1cDt60M8uoZZTzPgoU598ilDjYEETwyGyCi79S3A3ix8oDaJLhM8stPOHLUeglKrkwxOFglzVs7bULjzxZlygZujsHfWu16cjp_P3b4TIH_hiH0-Cjin-EVt4va2TnfGJ8HDxHxzWn7g')
|
141
|
-
|
142
|
-
converted_token = JsonWebToken.from_jwe(jwe_s,
|
143
|
-
private_key: test_private_key)
|
144
|
-
|
145
|
-
expect(converted_token.to_h).to eql [
|
146
|
-
{ 'foo' => 'bar' },
|
147
|
-
{ 'typ' => 'JWT', 'alg' => 'RS256' },
|
148
|
-
]
|
149
|
-
end
|
150
|
-
# rubocop:enable Metrics/LineLength
|
151
|
-
|
152
|
-
it 'can accept roles as a string but convert them to an array' do
|
153
|
-
token = JsonWebToken.new(data: { 'rol' => 'bar,baz' },
|
154
|
-
private_key: test_private_key)
|
155
|
-
|
156
|
-
expect(token.roles).to eql %w{bar baz}
|
157
|
-
|
158
|
-
jwe_s = token.to_jwe_s
|
159
|
-
|
160
|
-
converted_token = JsonWebToken.from_jwe(jwe_s,
|
161
|
-
private_key: test_private_key)
|
162
|
-
|
163
|
-
expect(converted_token.data['rol']).to eql 'bar,baz'
|
164
|
-
expect(converted_token.roles).to eql %w{bar baz}
|
165
|
-
end
|
166
|
-
|
167
|
-
it 'can build a token by explicitly specifying all the data', :time_mock do
|
168
|
-
token = JsonWebToken.build(id: 'test_id',
|
169
|
-
audience: 'audience',
|
170
|
-
expiration: 20.years.from_now,
|
171
|
-
issuer: 'issuer',
|
172
|
-
issued_at: 5.minutes.ago,
|
173
|
-
not_before: 1.month.ago,
|
174
|
-
owner: 'subject_id',
|
175
|
-
roles: %w{my_role},
|
176
|
-
subject: 'my_subject',
|
177
|
-
subject_id: 'subject_id',
|
178
|
-
token_private_key: test_private_key)
|
179
|
-
|
180
|
-
jwe_s = token.to_jwe_s
|
181
|
-
|
182
|
-
converted_token = JsonWebToken.from_jwe(jwe_s,
|
183
|
-
private_key: test_private_key)
|
184
|
-
|
185
|
-
expect(converted_token.to_h).to eql(
|
186
|
-
[
|
187
|
-
{
|
188
|
-
'aud' => 'audience',
|
189
|
-
'exp' => 1_974_477_600,
|
190
|
-
'iat' => 1_343_325_300,
|
191
|
-
'iss' => 'issuer',
|
192
|
-
'jti' => 'test_id',
|
193
|
-
'nbf' => 1_340_733_600,
|
194
|
-
'own' => 'subject_id',
|
195
|
-
'rol' => 'my_role',
|
196
|
-
'sid' => 'subject_id',
|
197
|
-
'sub' => 'my_subject',
|
198
|
-
},
|
199
|
-
{
|
200
|
-
'typ' => 'JWT',
|
201
|
-
'alg' => 'RS256',
|
202
|
-
},
|
203
|
-
],
|
204
|
-
)
|
205
|
-
end
|
206
|
-
|
207
|
-
it 'can build a token by only specifying the subject ID', :time_mock do
|
208
|
-
token = JsonWebToken.build(subject_id: 'subject_id',
|
209
|
-
token_private_key: test_private_key)
|
210
|
-
|
211
|
-
jwe_s = token.to_jwe_s
|
212
|
-
|
213
|
-
converted_token = JsonWebToken.from_jwe(jwe_s,
|
214
|
-
private_key: test_private_key)
|
215
|
-
|
216
|
-
expect(converted_token.to_h).to include(
|
217
|
-
'aud' => 'public',
|
218
|
-
'exp' => 1_343_930_400,
|
219
|
-
'iat' => 1_343_325_600,
|
220
|
-
'iss' => 'drillbit',
|
221
|
-
'jti' => match(uuid_regex),
|
222
|
-
'nbf' => 1_343_325_600,
|
223
|
-
'own' => 'subject_id',
|
224
|
-
'rol' => 'standard',
|
225
|
-
'sid' => 'subject_id',
|
226
|
-
'sub' => 'User',
|
227
|
-
)
|
228
|
-
end
|
229
|
-
end
|
230
|
-
end
|
231
|
-
end
|