macmillan-utils 1.0.15 → 1.0.16

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f21b8489a845791b540628d4bd8c83f8b8bb8c0a
4
- data.tar.gz: 10b5379ccfb3179f6aaebabdbae667b72bdfd4df
3
+ metadata.gz: a55ad2739730efad268195c547a7e32778b01a24
4
+ data.tar.gz: 7fdcb527d586d86710b39f37109fbeb43f9d6714
5
5
  SHA512:
6
- metadata.gz: 70e07de17d2025f9c9852461e937913413107382ac979cc624bd7561a6a8f1e8fcc5711a36ba21420ee14b008a12c4ce9be33654e3273c686461081c3c42170e
7
- data.tar.gz: 303455c3d6ca9cffc2188efdb8c1aa6f65a5948ba4b8f2ab78d23ac5945db13b64595449c70cbcbb8d6a25b6c1a8679f8c7605398b8130f0dfa1fe1318e346e8
6
+ metadata.gz: 7610595d1d34f5302efc6c0eda3005addc1ec698d490c872b0ac85a04c1f8a69646ee650ed373d0afacd7ca94c91ee2cd70d438c2d082b838fac01a65b25cdbc
7
+ data.tar.gz: 01578efea5492224685f7ddfddcaf25efcd262f24f7f6f45b9c2f8dd4287ffb2f8aef1f9ec8c1b9a2647082d1f03100a970e8f460318f65b78857f6abb781ecb
data/.travis.yml CHANGED
@@ -11,5 +11,6 @@ rvm:
11
11
  - 2.1.5
12
12
  - 2.2.0
13
13
  - jruby-19mode
14
+ - rbx-2
14
15
  env:
15
16
  - USE_SIMPLECOV=true CODECLIMATE_REPO_TOKEN=2175628fb41494d45b50b6938600a53c130e1f7ac3b81b072bb71e91073a5e4a
@@ -2,6 +2,7 @@ module Macmillan
2
2
  module Utils
3
3
  module Middleware
4
4
  autoload :WeakEtags, 'macmillan/utils/middleware/weak_etags'
5
+ autoload :Uuid, 'macmillan/utils/middleware/uuid'
5
6
  end
6
7
  end
7
8
  end
@@ -0,0 +1,89 @@
1
+ module Macmillan
2
+ module Utils
3
+ module Middleware
4
+ ##
5
+ # Rack Middleware for uniquley identifying a user.
6
+ #
7
+ # If the user is logged in, their UUID will be based upon their user_id, otherwise
8
+ # it will be randomly generated. This UUID will be stored in the rack env, and
9
+ # persisted in a cookie.
10
+ #
11
+ # This middleware expects a user object to be stored in the rack env.
12
+ #
13
+ class Uuid
14
+ def self.env_key
15
+ 'user.uuid'
16
+ end
17
+
18
+ def initialize(app, opts={})
19
+ @app = app
20
+ @user_env_key = opts[:user_env_key] || 'current_user'
21
+ @user_id_method = opts[:user_id_method] || 'user_id'
22
+ end
23
+
24
+ class CallHandler
25
+ attr_reader :app, :request, :user_env_key, :user_id_method, :cookie_key
26
+
27
+ def initialize(env, app, user_env_key, user_id_method, cookie_key)
28
+ @app = app
29
+ @request = Rack::Request.new(env)
30
+ @user_env_key = user_env_key
31
+ @user_id_method = user_id_method
32
+ @cookie_key = cookie_key
33
+
34
+ env[cookie_key] = user_uuid
35
+ end
36
+
37
+ def response
38
+ @response ||= begin
39
+ status, headers, body = app.call(request.env)
40
+ Rack::Response.new(body, status, headers)
41
+ end
42
+ end
43
+
44
+ def finish
45
+ save_cookie if store_cookie?
46
+ response.finish
47
+ end
48
+
49
+ def user
50
+ request.env[user_env_key]
51
+ end
52
+
53
+ def user_uuid
54
+ @user_uuid ||= begin
55
+ if user
56
+ Digest::SHA1.hexdigest(user.public_send(user_id_method).to_s)
57
+ elsif cookie_uuid
58
+ cookie_uuid
59
+ else
60
+ SecureRandom.uuid
61
+ end
62
+ end
63
+ end
64
+
65
+ def cookie_uuid
66
+ request.cookies[cookie_key]
67
+ end
68
+
69
+ def store_cookie?
70
+ user_uuid != cookie_uuid
71
+ end
72
+
73
+ def save_cookie
74
+ response.set_cookie(cookie_key, { value: user_uuid, path: '/', expires: DateTime.now.next_year.to_time })
75
+ end
76
+ end
77
+
78
+ def call(env)
79
+ dup.process(env)
80
+ end
81
+
82
+ def process(env)
83
+ handler = CallHandler.new(env, @app, @user_env_key, @user_id_method, self.class.env_key)
84
+ handler.finish
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
@@ -24,8 +24,7 @@ module Macmillan
24
24
  env['HTTP_IF_NONE_MATCH'] = etag.gsub(/^W\//, '')
25
25
  end
26
26
 
27
- status, headers, body = @app.call(env)
28
- [status, headers, body]
27
+ @app.call(env)
29
28
  end
30
29
  end
31
30
  end
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe Macmillan::Utils::Middleware::Uuid do
4
+ let(:app) { ->(env) { [200, env, 'app'] } }
5
+ let(:request) { req_for('http://example.com') }
6
+ let(:user) { double(email: 'bob.flemming@cough.com', user_id: '12345') }
7
+ let(:user_uuid) { Digest::SHA1.hexdigest(user.user_id.to_s) }
8
+
9
+ subject { Macmillan::Utils::Middleware::Uuid.new(app) }
10
+
11
+ context 'when we have a logged in user' do
12
+ before do
13
+ request.env['current_user'] = user
14
+ end
15
+
16
+ context 'who has not visited before' do
17
+ it 'sets the user_uuid cookie' do
18
+ _status, headers, _body = subject.call(request.env)
19
+ expect(headers['Set-Cookie']).to include(user_uuid)
20
+ end
21
+
22
+ it 'stores the user_uuid in the env' do
23
+ _status, headers, _body = subject.call(request.env)
24
+ expect(headers['user.uuid']).to eq(user_uuid)
25
+ end
26
+ end
27
+
28
+ context 'who also has a randomly assigned user_uuid cookie (from a previous non-authenticated session)' do
29
+ before do
30
+ request.cookies['user.uuid'] = 'qwerty'
31
+ end
32
+
33
+ it 'replaces this cookie with one based on the users user_id' do
34
+ _status, headers, _body = subject.call(request.env)
35
+ expect(headers['Set-Cookie']).to include("user.uuid=#{user_uuid}")
36
+ end
37
+ end
38
+ end
39
+
40
+ context 'when we have a non-logged in user' do
41
+ before do
42
+ request.env['current_user'] = nil
43
+ allow(SecureRandom).to receive(:uuid).and_return('wibble')
44
+ end
45
+
46
+ context 'who has not visited before' do
47
+ it 'stores the auto-generated UUID in the env' do
48
+ _status, headers, _body = subject.call(request.env)
49
+ expect(headers['user.uuid']).to eq('wibble')
50
+ end
51
+
52
+ it 'sets the user_uuid cookie' do
53
+ _status, headers, _body = subject.call(request.env)
54
+ expect(headers['Set-Cookie']).to include('user.uuid=wibble')
55
+ end
56
+ end
57
+
58
+ context 'who has visited before and has a user_uuid cookie' do
59
+ before do
60
+ request.cookies['user.uuid'] = 'qwerty'
61
+ end
62
+
63
+ it 'stores the user_uuid (from the cookie) in the env' do
64
+ _status, headers, _body = subject.call(request.env)
65
+ expect(headers['user.uuid']).to eq('qwerty')
66
+ end
67
+
68
+ it 'does not try to replace the cookie' do
69
+ _status, headers, _body = subject.call(request.env)
70
+ expect(headers['Set-Cookie']).to be_nil
71
+ end
72
+ end
73
+ end
74
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: macmillan-utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.15
4
+ version: 1.0.16
5
5
  platform: ruby
6
6
  authors:
7
7
  - Macmillan Science and Education (New Publsihing Platforms)
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-06 00:00:00.000000000 Z
11
+ date: 2015-02-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -230,6 +230,7 @@ files:
230
230
  - lib/macmillan/utils/logger/factory.rb
231
231
  - lib/macmillan/utils/logger/formatter.rb
232
232
  - lib/macmillan/utils/middleware.rb
233
+ - lib/macmillan/utils/middleware/uuid.rb
233
234
  - lib/macmillan/utils/middleware/weak_etags.rb
234
235
  - lib/macmillan/utils/rails/statsd_instrumentation.rb
235
236
  - lib/macmillan/utils/rspec/rack_test_helper.rb
@@ -252,6 +253,7 @@ files:
252
253
  - spec/fixtures/config/application.yml
253
254
  - spec/lib/macmillan/utils/logger/factory_spec.rb
254
255
  - spec/lib/macmillan/utils/logger/formatter_spec.rb
256
+ - spec/lib/macmillan/utils/middleware/uuid_spec.rb
255
257
  - spec/lib/macmillan/utils/middleware/weak_etags_spec.rb
256
258
  - spec/lib/macmillan/utils/settings_spec.rb
257
259
  - spec/lib/macmillan/utils/statsd_controller_helper_spec.rb
@@ -287,6 +289,7 @@ test_files:
287
289
  - spec/fixtures/config/application.yml
288
290
  - spec/lib/macmillan/utils/logger/factory_spec.rb
289
291
  - spec/lib/macmillan/utils/logger/formatter_spec.rb
292
+ - spec/lib/macmillan/utils/middleware/uuid_spec.rb
290
293
  - spec/lib/macmillan/utils/middleware/weak_etags_spec.rb
291
294
  - spec/lib/macmillan/utils/settings_spec.rb
292
295
  - spec/lib/macmillan/utils/statsd_controller_helper_spec.rb