hoodoo 1.0.4 → 1.0.5

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.
@@ -4,13 +4,17 @@
4
4
 
5
5
  require 'spec_helper'
6
6
 
7
+ # Used for X-Assume-Identity-Of testing to avoid magic value copy-and-paste.
8
+ #
9
+ VALID_ASSUMED_IDENTITY_HASH ||= { 'caller_id' => 'custom_caller_id' }
10
+
7
11
  # This gets inter-resource called from ...BImplementation. It expects search
8
12
  # data containing an 'offset' key and string/integer value. If > 0, an error
9
13
  # is triggered quoting the offset value in the reference data; else a hook
10
14
  # method is called that we can check with RSpec.
11
15
  #
12
16
  # It contains one public action, to test public-to-public calling from ...B.
13
-
17
+ #
14
18
  class RSpecTestInterResourceCallsAImplementation < Hoodoo::Services::Implementation
15
19
 
16
20
  def list( context )
@@ -33,6 +37,8 @@ class RSpecTestInterResourceCallsAImplementation < Hoodoo::Services::Implementat
33
37
  :message => 'Returning error as requested',
34
38
  :reference => { :another => 'no other ident', :field_name => 'no ident' }
35
39
  )
40
+ elsif context.request.ident == 'hello_return_identity' || context.request.ident == 'hello_set_good_inter_resource_identity'
41
+ context.response.set_resource( { 'identity' => context.session.identity.to_h } )
36
42
  else
37
43
  context.response.set_resource( { 'inner' => 'shown' } )
38
44
  end
@@ -155,8 +161,18 @@ class RSpecTestInterResourceCallsBImplementation < Hoodoo::Services::Implementat
155
161
  {}
156
162
  )
157
163
  else
158
- result = context.resource( :RSpecTestInterResourceCallsAResource ).show(
159
- 'hello' + context.request.ident,
164
+ resource = context.resource( :RSpecTestInterResourceCallsAResource )
165
+
166
+ if ( context.request.ident == 'set_bad_inter_resource_identity' )
167
+ resource.assume_identity_of = {
168
+ VALID_ASSUMED_IDENTITY_HASH.keys.first => Hoodoo::UUID.generate
169
+ }
170
+ elsif ( context.request.ident == 'set_good_inter_resource_identity' )
171
+ resource.assume_identity_of = VALID_ASSUMED_IDENTITY_HASH
172
+ end
173
+
174
+ result = resource.show(
175
+ 'hello_' + context.request.ident,
160
176
  { :_embed => :foo }
161
177
  )
162
178
  end
@@ -177,7 +193,7 @@ class RSpecTestInterResourceCallsBImplementation < Hoodoo::Services::Implementat
177
193
  # in their top-level call with permission, 'body' will contain 'id'
178
194
  # and that'll be rejected if we pass it through an inter-resource call
179
195
  # (you must use the high-level interface to do that), assuming things
180
- # are working properly andthe X-Resource-UUID specification is *not*
196
+ # are working properly and the X-Resource-UUID specification is *not*
181
197
  # automatically inherited to inter-resource endpoints.
182
198
  #
183
199
  # This is for *top level* calls specifying UUIDs to *this resource*.
@@ -234,7 +250,7 @@ class RSpecTestInterResourceCallsBImplementation < Hoodoo::Services::Implementat
234
250
  def update( context )
235
251
  expectable_hook( context )
236
252
  result = context.resource( :RSpecTestInterResourceCallsAResource ).update(
237
- 'hello' + context.request.ident,
253
+ 'hello_' + context.request.ident,
238
254
  context.request.body,
239
255
  { :_embed => 'foo' }
240
256
  )
@@ -248,7 +264,7 @@ class RSpecTestInterResourceCallsBImplementation < Hoodoo::Services::Implementat
248
264
 
249
265
  expectable_hook( context )
250
266
  result = context.resource( :RSpecTestInterResourceCallsAResource ).delete(
251
- 'hello' + context.request.ident,
267
+ 'hello_' + context.request.ident,
252
268
  { :_embed => [ :foo ] }
253
269
  )
254
270
  expectable_result_hook( result )
@@ -536,8 +552,8 @@ describe Hoodoo::Services::Middleware::InterResourceLocal do
536
552
  expect(context.owning_interaction.interaction_id).to eq(@interaction_id)
537
553
  expect(context.request.body).to be_nil
538
554
  expect(context.request.embeds).to eq(['foo'])
539
- expect(context.request.uri_path_components).to eq(['helloworld'])
540
- expect(context.request.ident).to eq('helloworld')
555
+ expect(context.request.uri_path_components).to eq(['hello_world'])
556
+ expect(context.request.ident).to eq('hello_world')
541
557
  expect(context.request.uri_path_extension).to eq('')
542
558
  expect(context.request.list.offset).to eq(0)
543
559
  expect(context.request.list.limit).to eq(50)
@@ -865,8 +881,8 @@ describe Hoodoo::Services::Middleware::InterResourceLocal do
865
881
  expect(context.owning_interaction.interaction_id).to eq(@interaction_id)
866
882
  expect(context.request.body).to eq({'sum' => 70})
867
883
  expect(context.request.embeds).to eq(['foo'])
868
- expect(context.request.uri_path_components).to eq(['helloworld'])
869
- expect(context.request.ident).to eq('helloworld')
884
+ expect(context.request.uri_path_components).to eq(['hello_world'])
885
+ expect(context.request.ident).to eq('hello_world')
870
886
  expect(context.request.locale).to eq(locale || 'en-nz')
871
887
  expect(context.request.dated_at).to eq(nil) # Not used => expect 'nil'
872
888
  expect(context.request.dated_from).to eq(nil) # Not used => expect 'nil'
@@ -943,8 +959,8 @@ describe Hoodoo::Services::Middleware::InterResourceLocal do
943
959
  expect(context.owning_interaction.interaction_id).to eq(@interaction_id)
944
960
  expect(context.request.body).to be_nil
945
961
  expect(context.request.embeds).to eq(['foo'])
946
- expect(context.request.uri_path_components).to eq(['helloworld'])
947
- expect(context.request.ident).to eq('helloworld')
962
+ expect(context.request.uri_path_components).to eq(['hello_world'])
963
+ expect(context.request.ident).to eq('hello_world')
948
964
  expect(context.request.locale).to eq(locale || 'en-nz')
949
965
  expect(context.request.dated_at).to eq(nil) # Not used => expect 'nil'
950
966
  expect(context.request.dated_from).to eq(nil) # Not used => expect 'nil'
@@ -1049,7 +1065,7 @@ describe Hoodoo::Services::Middleware::InterResourceLocal do
1049
1065
  # <- B
1050
1066
  expect_any_instance_of(RSpecTestInterResourceCallsBImplementation).to receive(:expectable_result_hook).once.and_call_original
1051
1067
 
1052
- get '/v1/rspec_test_inter_resource_calls_b/_return_error', nil, { 'CONTENT_TYPE' => 'application/json; charset=utf-8' }
1068
+ get '/v1/rspec_test_inter_resource_calls_b/return_error', nil, { 'CONTENT_TYPE' => 'application/json; charset=utf-8' }
1053
1069
  expect(last_response.status).to eq(422)
1054
1070
  result = JSON.parse(last_response.body)
1055
1071
  expect( result[ 'errors' ] ).to_not be_nil
@@ -1060,6 +1076,122 @@ describe Hoodoo::Services::Middleware::InterResourceLocal do
1060
1076
  })
1061
1077
  end
1062
1078
 
1079
+ context 'X-Assume-Identity-Of' do
1080
+ context 'top-level use permitted' do
1081
+ before :each do
1082
+ @old_test_session = Hoodoo::Services::Middleware.test_session()
1083
+
1084
+ test_session = @old_test_session.dup
1085
+ test_session.identity = test_session.identity.dup
1086
+ test_session.scoping = test_session.scoping.dup
1087
+
1088
+ test_session.scoping.authorised_http_headers = [ 'X-Assume-Identity-Of' ]
1089
+ test_session.scoping.authorised_identities = {
1090
+ VALID_ASSUMED_IDENTITY_HASH.keys.first =>
1091
+ [ VALID_ASSUMED_IDENTITY_HASH.values.first ]
1092
+ }
1093
+
1094
+ Hoodoo::Services::Middleware.set_test_session( test_session )
1095
+ end
1096
+
1097
+ after :each do
1098
+ Hoodoo::Services::Middleware.set_test_session( @old_test_session )
1099
+ end
1100
+
1101
+ context 'when in use at top level' do
1102
+ it 'sees correct identity in the downstream resource' do
1103
+ get(
1104
+ '/v1/rspec_test_inter_resource_calls_b/return_identity',
1105
+ nil,
1106
+ {
1107
+ 'CONTENT_TYPE' => 'application/json; charset=utf-8',
1108
+ 'HTTP_X_ASSUME_IDENTITY_OF' => URI.encode_www_form( VALID_ASSUMED_IDENTITY_HASH )
1109
+ }
1110
+ )
1111
+
1112
+ result = JSON.parse( last_response.body )
1113
+ expect( result[ 'result' ][ 'identity' ] ).to eq( VALID_ASSUMED_IDENTITY_HASH )
1114
+ end
1115
+
1116
+ it 'cannot set an illegal identity in the inter-resource call' do
1117
+ get(
1118
+ '/v1/rspec_test_inter_resource_calls_b/set_bad_inter_resource_identity',
1119
+ nil,
1120
+ {
1121
+ 'CONTENT_TYPE' => 'application/json; charset=utf-8',
1122
+ 'HTTP_X_ASSUME_IDENTITY_OF' => URI.encode_www_form( VALID_ASSUMED_IDENTITY_HASH )
1123
+ }
1124
+ )
1125
+
1126
+ expect( last_response.status ).to eq( 403 )
1127
+ result = JSON.parse( last_response.body )
1128
+ expect( result[ 'errors' ][ 0 ][ 'message' ] ).to eq( 'X-Assume-Identity-Of header value requests a prohibited identity quantity' )
1129
+ end
1130
+ end
1131
+
1132
+ context 'in inter-resource call only' do
1133
+ identity_hash = { 'caller_id' => 'custom_caller_id' }
1134
+
1135
+ it 'can still set identity for the downstream resource' do
1136
+ get(
1137
+ '/v1/rspec_test_inter_resource_calls_b/set_good_inter_resource_identity',
1138
+ nil,
1139
+ { 'CONTENT_TYPE' => 'application/json; charset=utf-8' }
1140
+ )
1141
+
1142
+ result = JSON.parse( last_response.body )
1143
+ expect( result[ 'result' ][ 'identity' ] ).to eq( VALID_ASSUMED_IDENTITY_HASH )
1144
+ end
1145
+
1146
+ it 'cannot set an illegal identity for the downstream resource' do
1147
+ get(
1148
+ '/v1/rspec_test_inter_resource_calls_b/set_bad_inter_resource_identity',
1149
+ nil,
1150
+ { 'CONTENT_TYPE' => 'application/json; charset=utf-8' }
1151
+ )
1152
+
1153
+ expect( last_response.status ).to eq( 403 )
1154
+ result = JSON.parse( last_response.body )
1155
+ expect( result[ 'errors' ][ 0 ][ 'message' ] ).to eq( 'X-Assume-Identity-Of header value requests a prohibited identity quantity' )
1156
+ end
1157
+ end
1158
+ end
1159
+
1160
+ context 'top-level use prohibited' do
1161
+ before :each do
1162
+ @old_test_session = Hoodoo::Services::Middleware.test_session()
1163
+
1164
+ test_session = @old_test_session.dup
1165
+ test_session.identity = test_session.identity.dup
1166
+ test_session.scoping = test_session.scoping.dup
1167
+
1168
+ test_session.scoping.authorised_http_headers = [] # NO ALLOWED HEADERS
1169
+ test_session.scoping.authorised_identities = { 'caller_id' => [ 'custom_caller_id' ] }
1170
+
1171
+ Hoodoo::Services::Middleware.set_test_session( test_session )
1172
+ end
1173
+
1174
+ after :each do
1175
+ Hoodoo::Services::Middleware.set_test_session( @old_test_session )
1176
+ end
1177
+
1178
+ # middleware_assumed_identity_spec.rb already comprehensively tests
1179
+ # top-level calls, so just do the inter-resource check here.
1180
+ #
1181
+ it 'cannot override a valid identity in inter-resource calls' do
1182
+ get(
1183
+ '/v1/rspec_test_inter_resource_calls_b/set_good_inter_resource_identity',
1184
+ nil,
1185
+ { 'CONTENT_TYPE' => 'application/json; charset=utf-8' }
1186
+ )
1187
+
1188
+ expect( last_response.status ).to eq( 403 )
1189
+ result = JSON.parse( last_response.body )
1190
+ expect( result[ 'errors' ][ 0 ][ 'message' ] ).to eq( 'Action not authorized' )
1191
+ end
1192
+ end
1193
+ end
1194
+
1063
1195
  it 'should get told if an action is not supported' do
1064
1196
  expect_any_instance_of(RSpecTestInterResourceCallsCImplementation).to_not receive(:show)
1065
1197
  expect_any_instance_of(RSpecTestInterResourceCallsCImplementation).to_not receive(:expectable_hook)
@@ -8,9 +8,13 @@
8
8
  require 'spec_helper'
9
9
  require 'json'
10
10
 
11
+ # Used for X-Assume-Identity-Of testing to avoid magic value copy-and-paste.
12
+ #
13
+ VALID_ASSUMED_IDENTITY_HASH ||= { 'caller_id' => 'custom_caller_id' }
14
+
11
15
  # First, a test service comprised of a couple of 'echo' variants which we use
12
16
  # to make sure they're both correctly stored in the DRb registry.
13
-
17
+ #
14
18
  class TestEchoImplementation < Hoodoo::Services::Implementation
15
19
 
16
20
  public
@@ -41,8 +45,10 @@ class TestEchoImplementation < Hoodoo::Services::Implementation
41
45
  :message => 'Returning error as requested',
42
46
  :reference => { :another => 'no other ident', :field_name => 'no ident' }
43
47
  )
44
- elsif context.request.uri_path_components[ 0 ] == 'return_invalid_json'
48
+ elsif context.request.uri_path_components[ 0 ] == 'return_invalid_data'
45
49
  context.response.body = 'Hello, world'
50
+ elsif context.request.ident == 'return_identity' || context.request.ident == 'set_good_inter_resource_identity'
51
+ context.response.body = { 'identity' => context.session.identity.to_h }
46
52
  else
47
53
  context.response.body = { 'show' => TestEchoImplementation.to_h( context ) }
48
54
  end
@@ -208,6 +214,14 @@ class TestCallImplementation < Hoodoo::Services::Implementation
208
214
  context.resource( :TestEcho, 2 )
209
215
  end
210
216
 
217
+ if ( context.request.ident == 'set_bad_inter_resource_identity' )
218
+ resource.assume_identity_of = {
219
+ VALID_ASSUMED_IDENTITY_HASH.keys.first => Hoodoo::UUID.generate
220
+ }
221
+ elsif ( context.request.ident == 'set_good_inter_resource_identity' )
222
+ resource.assume_identity_of = VALID_ASSUMED_IDENTITY_HASH
223
+ end
224
+
211
225
  result = resource.show(
212
226
  context.request.uri_path_components.join( ',' ),
213
227
  {
@@ -1067,6 +1081,135 @@ describe Hoodoo::Services::Middleware do
1067
1081
  expect(result['errors'][0]['code']).to eq('generic.invalid_string')
1068
1082
  end
1069
1083
 
1084
+ it 'gets the correct type back when an inter-resource remote call returns invalid data' do
1085
+ expect_any_instance_of( TestCallImplementation ).to receive( :expectable_result_hook ) do | instance, result |
1086
+ expect( result ).to be_a( Hoodoo::Client::AugmentedHash )
1087
+ expect( result.platform_errors.has_errors? ).to eq( true )
1088
+ end
1089
+
1090
+ get( '/v1/test_call/return_invalid_data', nil, headers_for() )
1091
+
1092
+ result = JSON.parse(last_response.body)
1093
+ expect(result['errors'][0]['code']).to eq('platform.fault')
1094
+ expect(result['errors'][0]['message']).to eq('Could not parse body data returned from inter-resource call despite receiving HTTP status code 200')
1095
+ end
1096
+
1097
+ context 'X-Assume-Identity-Of' do
1098
+ context 'top-level use permitted' do
1099
+ before :each do
1100
+ @old_test_session = Hoodoo::Services::Middleware.test_session()
1101
+
1102
+ test_session = @old_test_session.dup
1103
+ test_session.identity = test_session.identity.dup
1104
+ test_session.scoping = test_session.scoping.dup
1105
+
1106
+ test_session.scoping.authorised_http_headers = [ 'X-Assume-Identity-Of' ]
1107
+ test_session.scoping.authorised_identities = {
1108
+ VALID_ASSUMED_IDENTITY_HASH.keys.first =>
1109
+ [ VALID_ASSUMED_IDENTITY_HASH.values.first ]
1110
+ }
1111
+
1112
+ Hoodoo::Services::Middleware.set_test_session( test_session )
1113
+ end
1114
+
1115
+ after :each do
1116
+ Hoodoo::Services::Middleware.set_test_session( @old_test_session )
1117
+ end
1118
+
1119
+ context 'when in use at top level' do
1120
+ it 'sees correct identity in the downstream resource' do
1121
+ get(
1122
+ '/v1/test_call/return_identity',
1123
+ nil,
1124
+ {
1125
+ 'CONTENT_TYPE' => 'application/json; charset=utf-8',
1126
+ 'HTTP_X_ASSUME_IDENTITY_OF' => URI.encode_www_form( VALID_ASSUMED_IDENTITY_HASH )
1127
+ }
1128
+ )
1129
+
1130
+ result = JSON.parse( last_response.body )
1131
+ expect( result[ 'show' ][ 'identity' ] ).to eq( VALID_ASSUMED_IDENTITY_HASH )
1132
+ end
1133
+
1134
+ it 'cannot set an illegal identity in the inter-resource call' do
1135
+ get(
1136
+ '/v1/test_call/set_bad_inter_resource_identity',
1137
+ nil,
1138
+ {
1139
+ 'CONTENT_TYPE' => 'application/json; charset=utf-8',
1140
+ 'HTTP_X_ASSUME_IDENTITY_OF' => URI.encode_www_form( VALID_ASSUMED_IDENTITY_HASH )
1141
+ }
1142
+ )
1143
+
1144
+ expect( last_response.status ).to eq( 403 )
1145
+ result = JSON.parse( last_response.body )
1146
+ expect( result[ 'errors' ][ 0 ][ 'message' ] ).to eq( 'X-Assume-Identity-Of header value requests a prohibited identity quantity' )
1147
+ end
1148
+ end
1149
+
1150
+ context 'in inter-resource call only' do
1151
+ identity_hash = { 'caller_id' => 'custom_caller_id' }
1152
+
1153
+ it 'can still set identity for the downstream resource' do
1154
+ get(
1155
+ '/v1/test_call/set_good_inter_resource_identity',
1156
+ nil,
1157
+ { 'CONTENT_TYPE' => 'application/json; charset=utf-8' }
1158
+ )
1159
+
1160
+ result = JSON.parse( last_response.body )
1161
+ expect( result[ 'show' ][ 'identity' ] ).to eq( VALID_ASSUMED_IDENTITY_HASH )
1162
+ end
1163
+
1164
+ it 'cannot set an illegal identity for the downstream resource' do
1165
+ get(
1166
+ '/v1/test_call/set_bad_inter_resource_identity',
1167
+ nil,
1168
+ { 'CONTENT_TYPE' => 'application/json; charset=utf-8' }
1169
+ )
1170
+
1171
+ expect( last_response.status ).to eq( 403 )
1172
+ result = JSON.parse( last_response.body )
1173
+ expect( result[ 'errors' ][ 0 ][ 'message' ] ).to eq( 'X-Assume-Identity-Of header value requests a prohibited identity quantity' )
1174
+ end
1175
+ end
1176
+ end
1177
+
1178
+ context 'top-level use prohibited' do
1179
+ before :each do
1180
+ @old_test_session = Hoodoo::Services::Middleware.test_session()
1181
+
1182
+ test_session = @old_test_session.dup
1183
+ test_session.identity = test_session.identity.dup
1184
+ test_session.scoping = test_session.scoping.dup
1185
+
1186
+ test_session.scoping.authorised_http_headers = [] # NO ALLOWED HEADERS
1187
+ test_session.scoping.authorised_identities = { 'caller_id' => [ 'custom_caller_id' ] }
1188
+
1189
+ Hoodoo::Services::Middleware.set_test_session( test_session )
1190
+ end
1191
+
1192
+ after :each do
1193
+ Hoodoo::Services::Middleware.set_test_session( @old_test_session )
1194
+ end
1195
+
1196
+ # middleware_assumed_identity_spec.rb already comprehensively tests
1197
+ # top-level calls, so just do the inter-resource check here.
1198
+ #
1199
+ it 'cannot override a valid identity in inter-resource calls' do
1200
+ get(
1201
+ '/v1/test_call/set_good_inter_resource_identity',
1202
+ nil,
1203
+ { 'CONTENT_TYPE' => 'application/json; charset=utf-8' }
1204
+ )
1205
+
1206
+ expect( last_response.status ).to eq( 403 )
1207
+ result = JSON.parse( last_response.body )
1208
+ expect( result[ 'errors' ][ 0 ][ 'message' ] ).to eq( 'Action not authorized' )
1209
+ end
1210
+ end
1211
+ end
1212
+
1070
1213
  def create_things( locale: nil, dated_from: nil, deja_vu: nil, resource_uuid: nil )
1071
1214
  post(
1072
1215
  '/v1/test_call.tar.gz',
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hoodoo
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Loyalty New Zealand
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-11 00:00:00.000000000 Z
11
+ date: 2016-01-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: uuidtools
@@ -463,6 +463,7 @@ files:
463
463
  - spec/services/middleware/exception_reporting/exception_reporting_spec.rb
464
464
  - spec/services/middleware/exception_reporting/reporters/airbrake_reporter_spec.rb
465
465
  - spec/services/middleware/exception_reporting/reporters/raygun_reporter_spec.rb
466
+ - spec/services/middleware/middleware_assumed_identity_spec.rb
466
467
  - spec/services/middleware/middleware_cors_spec.rb
467
468
  - spec/services/middleware/middleware_create_update_spec.rb
468
469
  - spec/services/middleware/middleware_dated_at_spec.rb
@@ -591,6 +592,7 @@ test_files:
591
592
  - spec/services/middleware/exception_reporting/exception_reporting_spec.rb
592
593
  - spec/services/middleware/exception_reporting/reporters/airbrake_reporter_spec.rb
593
594
  - spec/services/middleware/exception_reporting/reporters/raygun_reporter_spec.rb
595
+ - spec/services/middleware/middleware_assumed_identity_spec.rb
594
596
  - spec/services/middleware/middleware_cors_spec.rb
595
597
  - spec/services/middleware/middleware_create_update_spec.rb
596
598
  - spec/services/middleware/middleware_dated_at_spec.rb