macmillan-utils 1.0.15 → 1.0.16

Sign up to get free protection for your applications and to get access to all the features.
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