grape-tokeeo 0.0.2.2 → 0.0.3

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: 023c95fb8b0466a6552a05c247573a65ab5613aa
4
- data.tar.gz: 13216ac3c5c6fc28378594c5267d5f33a5490c53
3
+ metadata.gz: 6010c1196dfba1e2600d0083cd3a71011629bb9e
4
+ data.tar.gz: 3c335c1ad5a6f42436f26a79dd91b613499d0870
5
5
  SHA512:
6
- metadata.gz: d712dd1c2fb783c5c63b4e1c424e94c4393da3509448dad4b6d606f553db6e61551acc5d253515c9c8d99f7d6fd3d9e1316c458f9d9864eb15ad451aacae0c6c
7
- data.tar.gz: a66ed07c494c914b1a318ceb2327408373b695a70c709638b29d3652b9123cd226e80a8c5ac41a71ccb69caae5f9e13cbb7b141d827fa023e39c0e6eef9c681a
6
+ metadata.gz: 8de57a3ecbab2999b7c4cf6e35ba486c438405421c7b67cc7f8b1778cb6ceefdac5a8b8672496a2a107b3049906e645dc253c6b59b9a1d0653f997bd59685ef8
7
+ data.tar.gz: 14ab13e6818e42ef870dca034e13e7bdfbc66067cbd6ffeafec38fd33c004b8251382f755b4d0c501ddc760a92276b6ad749ea61174d422ccd53ca2a565ca456
@@ -3,7 +3,10 @@ cache: bundler
3
3
 
4
4
  rvm:
5
5
  - 2.1.2
6
-
6
+
7
+ services:
8
+ - mongodb
9
+
7
10
  script: 'bundle exec rspec'
8
11
 
9
12
  notifications:
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  [![Build Status](https://travis-ci.org/wawandco/grape-tokeeo.svg?branch=master)](https://travis-ci.org/wawandco/grape-tokeeo)
2
2
  [![Code Climate](https://codeclimate.com/github/wawandco/grape-tokeeo/badges/gpa.svg)](https://codeclimate.com/github/wawandco/grape-tokeeo)
3
3
  [![Test Coverage](https://codeclimate.com/github/wawandco/grape-tokeeo/badges/coverage.svg)](https://codeclimate.com/github/wawandco/grape-tokeeo)
4
+ [![Gem Version](https://badge.fury.io/rb/grape-tokeeo.svg)](http://badge.fury.io/rb/grape-tokeeo)
4
5
 
5
6
  # Grape::Tokeeo
6
7
 
@@ -40,7 +41,7 @@ And we don't want to expose :something publicly, grape-tokkeo helps us by allowi
40
41
 
41
42
  ```ruby
42
43
  class MyApi::API < Grape::API
43
- validate_token is: 'S0METHINGWEWANTTOSHAREONLYWITHCLIENT'
44
+ ensure_token is: 'S0METHINGWEWANTTOSHAREONLYWITHCLIENT'
44
45
 
45
46
  get :something do
46
47
  {content: 'secret content'}
@@ -53,7 +54,7 @@ In case we call the API without passing *X-Api-Token* with the 'S0METHINGWEWANTT
53
54
  this options also accepts a list of tokens inside the /is:/ option. like this.
54
55
  ```ruby
55
56
  class MyApi::API < Grape::API
56
- validate_token is: ['TOKENA','TOKENB']
57
+ ensure_token is: ['TOKENA','TOKENB']
57
58
 
58
59
  get :something do
59
60
  {content: 'secret content'}
@@ -64,11 +65,11 @@ end
64
65
 
65
66
  ### Token on model
66
67
 
67
- In case we want to ensure the token exists in a model we can use the following syntax for the *validate_token* method:
68
+ In case we want to ensure the token exists in a model we can use the following syntax for the *ensure_token* method:
68
69
 
69
70
  ```ruby
70
71
  class MyApi::API < Grape::API
71
- validate_token in: SecureTokenHolder, field: :token
72
+ ensure_token in: SecureTokenHolder, field: :token
72
73
 
73
74
  get :something do
74
75
  {content: 'secret content'}
@@ -78,13 +79,15 @@ end
78
79
 
79
80
  Again this should ensure the token exist by looking on the SecureTokenHolder model table for a record with the column 'token' with the same value as 'X-Api-Token'.
80
81
 
82
+ Starting from version 0.0.3 grape-tokeeo supports *ActiveRecord* , *MongoMapper* , *Mongoid* and *DataMapper* ORM libraries to handle this feature.
83
+
81
84
  ### Token validated against a block passed
82
85
 
83
- There may be some cases where you would like to do the validation by yourself or the validation logic is not simple as verifying against the model attribute, in that case we could pass a block to the *validate_token_in* method like:
86
+ There may be some cases where you would like to do the validation by yourself or the validation logic is not simple as verifying against the model attribute, in that case we could pass a block to the *ensure_token_with* method like:
84
87
 
85
88
  ```ruby
86
89
  class MyApi::API < Grape::API
87
- validate_token_with do |token|
90
+ ensure_token_with do |token|
88
91
  SomeComplexOperationHolder.validate token
89
92
  end
90
93
 
@@ -102,10 +105,24 @@ You can also define your custom validation error message by passing the /invalid
102
105
 
103
106
  ```ruby
104
107
  class MyApi::API < Grape::API
105
- validate_token is: ['TOKENA','TOKENB'], invalid_message: "Look 'ma its working"
108
+ ensure_token is: ['TOKENA','TOKENB'], invalid_message: "Look 'ma its working"
106
109
 
107
110
  get :something do
108
111
  {content: 'secret content'}
109
112
  end
110
113
  end
111
114
  ```
115
+
116
+ ### Custom missing token message
117
+
118
+ By default 'Token was not passed' message is defined when API token is missing in the request. You can customize this message by passing the *missing_message* option to the method:
119
+
120
+ ```ruby
121
+ class MyApi::API < Grape::API
122
+ ensure_token is: 'TOKENA', missing_message: 'API token is missing!'
123
+
124
+ get :something do
125
+ {content: 'secret content'}
126
+ end
127
+ end
128
+ ```
@@ -27,8 +27,13 @@ Gem::Specification.new do |spec|
27
27
  spec.add_development_dependency 'database_cleaner', '~> 1.3'
28
28
  spec.add_development_dependency "rack-test", '~> 0'
29
29
  spec.add_development_dependency "codeclimate-test-reporter", '~> 0'
30
-
30
+ spec.add_development_dependency "dm-sqlite-adapter", '~> 1.2'
31
+ spec.add_development_dependency "dm-core", '~> 1.2'
32
+ spec.add_development_dependency "dm-migrations", '~> 1.2'
33
+ spec.add_development_dependency "bson_ext", '~> 1.0'
34
+ spec.add_development_dependency "mongo_mapper", '~> 0.11'
31
35
 
32
36
  spec.add_runtime_dependency "grape", '~> 0.9'
33
37
  spec.add_runtime_dependency "activerecord", '~> 4'
38
+ spec.add_runtime_dependency "orm_adapter", '~> 0.5.0'
34
39
  end
@@ -6,13 +6,23 @@ module Grape
6
6
  include Grape::Tokeeo
7
7
 
8
8
  class << self
9
- def validate_token( options={} )
9
+ def ensure_token(options={})
10
10
  Grape::Tokeeo.build_preshared_token_security(options, self) if options[:is].present?
11
11
  Grape::Tokeeo.build_model_token_security(options, self) if options[:in].present?
12
12
  end
13
13
 
14
+ def ensure_token_with(options={}, &block)
15
+ Grape::Tokeeo.define_before_for(self, options, &block)
16
+ end
17
+
18
+ def validate_token(options={} )
19
+ warn "[DEPRECATED] 'validate_token' is deprecated, use 'ensure_token' instead"
20
+ ensure_token(options)
21
+ end
22
+
14
23
  def validate_token_with(options={}, &block)
15
- Grape::Tokeeo.secure_with( self, options, &block)
24
+ warn "[DEPRECATED] 'validate_token_with' is deprecated, use 'ensure_token_with' instead"
25
+ ensure_token_with(options, &block)
16
26
  end
17
27
  end
18
28
  end
@@ -29,6 +39,11 @@ module Grape
29
39
  invalid_message_to_use ||= DEFAULT_INVALID_MESSAGE
30
40
  end
31
41
 
42
+ def message_for_missing_token( options= {})
43
+ missing_message_to_use = options[:missing_message]
44
+ missing_message_to_use ||= DEFAULT_MISSING_MESSAGE
45
+ end
46
+
32
47
  def header_to_verify( options={} )
33
48
  header_to_use = options[:header]
34
49
  header_to_use ||= DEFAULT_HEADER
@@ -39,42 +54,50 @@ module Grape
39
54
  token ||= request.env[key]
40
55
  end
41
56
 
42
- def build_preshared_token_security(options, api_instance)
57
+ def header_token( options, request )
58
+ header_key = Grape::Tokeeo.header_to_verify(options)
59
+ token = Grape::Tokeeo.header_for( header_key, request )
60
+ end
61
+
62
+ def define_before_for(api_instance, options, &block)
43
63
  api_instance.before do
44
- header_key = Grape::Tokeeo.header_to_verify(options)
45
- token = Grape::Tokeeo.header_for( header_key, request )
46
- preshared_token = options[:is]
64
+ token = Grape::Tokeeo.header_token(options, request)
65
+ error!( Grape::Tokeeo.message_for_missing_token(options), 401) unless token.present?
66
+ error!( Grape::Tokeeo.message_for_invalid_token(options), 401) unless yield(token)
67
+ end
68
+ end
47
69
 
48
- error!(DEFAULT_MISSING_MESSAGE, 401) unless token.present?
70
+ def verification_passed?( options, token)
71
+ preshared_token = options[:is]
72
+ preshared_token.is_a?(Array) ? preshared_token.include?(token) : token == preshared_token
73
+ end
49
74
 
50
- verification_passed = preshared_token.is_a?(Array) ? preshared_token.include?(token) : token == preshared_token
51
- error!( Grape::Tokeeo.message_for_invalid_token(options) , 401) unless verification_passed
75
+ def build_preshared_token_security(options, api_instance)
76
+ define_before_for(api_instance, options) do |token|
77
+ Grape::Tokeeo.verification_passed?(options, token)
52
78
  end
53
79
  end
54
80
 
55
- def build_model_token_security(options, api_instance)
81
+ def use_supported_orm? (clazz)
82
+ supported = clazz < ActiveRecord::Base if defined?(ActiveRecord::Base)
83
+ supported ||= clazz < DataMapper::Resource if defined?(DataMapper::Resource)
84
+ supported ||= clazz < MongoMapper::Document if defined?(MongoMapper::Document)
85
+ supported ||= clazz < MongoMapper::EmbeddedDocument if defined?(MongoMapper::EmbeddedDocument)
86
+ supported ||= clazz < Mongoid::Document if defined?(Mongoid::Document)
87
+ supported
88
+ end
89
+
90
+ def found_in_model? (options, token)
56
91
  clazz = options[:in]
57
92
  field = options[:field]
58
93
 
59
- raise Error("#{clazz} is not an ActiveRecord::Base subclass") unless clazz < ActiveRecord::Base
60
-
61
- api_instance.before do
62
- header = Grape::Tokeeo.header_to_verify(options)
63
- token = env[header]
64
- found = clazz.find_by("#{field.to_s}" => token )
65
-
66
- error!(DEFAULT_MISSING_MESSAGE, 401) unless token.present?
67
- error!( Grape::Tokeeo.message_for_invalid_token(options), 401) unless found.present?
68
- end
94
+ raise Error("#{clazz} does not use any of the orm library supported") unless Grape::Tokeeo.use_supported_orm?(clazz)
95
+ clazz.to_adapter.find_first("#{field.to_s}" => token)
69
96
  end
70
97
 
71
- def secure_with(api_instance, options, &block )
72
- api_instance.before do
73
- header = Grape::Tokeeo.header_to_verify(options)
74
- token = env[header]
75
-
76
- error!( DEFAULT_MISSING_MESSAGE, 401) unless token.present?
77
- error!( Grape::Tokeeo.message_for_invalid_token(options), 401) unless yield(token)
98
+ def build_model_token_security(options, api_instance)
99
+ define_before_for(api_instance, options) do |token|
100
+ Grape::Tokeeo.found_in_model?(options, token)
78
101
  end
79
102
  end
80
103
  end
@@ -1,5 +1,5 @@
1
1
  module Grape
2
2
  module Tokeeo
3
- VERSION = "0.0.2.2"
3
+ VERSION = "0.0.3"
4
4
  end
5
5
  end
@@ -1,7 +1,18 @@
1
1
  FactoryGirl.define do
2
- factory :user do |user|
3
- sequence(:name) { |n| "name_#{n}" }
4
- sequence(:email) { |n| "email_#{n}@test.com" }
5
- token "#{SecureRandom.uuid}"
2
+
3
+ sequence(:name) { |n| "name_#{n}" }
4
+ sequence(:email) { |n| "email_#{n}@test.com" }
5
+ sequence(:token) { |n| "#{SecureRandom.uuid}"}
6
+
7
+ factory :user_active_record, class: User do |user|
8
+ name; email; token
9
+ end
10
+
11
+ factory :user_data_mapper, class: UserDataMapper do
12
+ name; email; token
13
+ end
14
+
15
+ factory :user_mongo_mapper, class: UserMongoMapper do
16
+ name; email; token
6
17
  end
7
18
  end
@@ -7,7 +7,7 @@ describe Grape::Tokeeo do
7
7
  APIExample.new
8
8
  end
9
9
 
10
- ['preshared', 'preshared_header', 'preshared_with_list', 'block', 'model'].each do |feature|
10
+ ['preshared', 'preshared_header', 'preshared_with_list', 'block', 'model_active_record'].each do |feature|
11
11
  context "##{feature} token" do
12
12
  it "should return 401 if X-Api-Token is not passed" do
13
13
  get "#{feature}/something"
@@ -52,11 +52,26 @@ describe Grape::Tokeeo do
52
52
  end
53
53
  end
54
54
 
55
- context "valid model one" do
56
- it "should return 200 if X-Api-Token is the same as the value user has defined" do
57
- create(:user, token: 'S0METHINGWEWANTTOSHAREONLYWITHCLIENT')
58
- get 'model/something', {}, {"X-Api-Token" => 'S0METHINGWEWANTTOSHAREONLYWITHCLIENT'}
59
- expect(last_response.status).to eq(200)
55
+ {
56
+ 'model_active_record' => :user_active_record,
57
+ 'model_data_mapper' => :user_data_mapper,
58
+ 'model_mongo_mapper' => :user_mongo_mapper
59
+ }.each do |resource, factory|
60
+
61
+ context "valid model one using #{resource}" do
62
+ it "should return 200 if X-Api-Token is the same as the value user has defined" do
63
+ create(factory, token: 'S0METHINGWEWANTTOSHAREONLYWITHCLIENT')
64
+ get "#{resource}/something", {}, {"X-Api-Token" => 'S0METHINGWEWANTTOSHAREONLYWITHCLIENT'}
65
+ expect(last_response.status).to eq(200)
66
+ end
67
+ end
68
+ end
69
+
70
+ context "valid wrong model" do
71
+ it "should raise error" do
72
+ expect {
73
+ get "wrong_model/something", {}, {"X-Api-Token" => 'S0METHINGWEWANTTOSHAREONLYWITHCLIENT'}
74
+ }.to raise_error
60
75
  end
61
76
  end
62
77
 
@@ -83,7 +98,7 @@ describe Grape::Tokeeo do
83
98
 
84
99
  context "valid model one" do
85
100
  it "should return 200 if X-My-Api-Header is the same as the value user has defined" do
86
- create(:user, token: 'S0METHINGWEWANTTOSHAREONLYWITHCLIENT')
101
+ create(:user_active_record, token: 'S0METHINGWEWANTTOSHAREONLYWITHCLIENT')
87
102
  get 'model_header/something', {}, {"X-My-Api-Header" => 'S0METHINGWEWANTTOSHAREONLYWITHCLIENT'}
88
103
  expect(last_response.status).to eq(200)
89
104
  end
@@ -95,4 +110,11 @@ describe Grape::Tokeeo do
95
110
  expect(last_response.status).to eq(200)
96
111
  end
97
112
  end
113
+
114
+ context "custom token is missing message" do
115
+ it "should return token is missing message if X-Api-Token is not passed" do
116
+ get 'missing_token_message/something'
117
+ expect(JSON.parse(last_response.body)['error']).to eq('API token is missing')
118
+ end
119
+ end
98
120
  end
@@ -8,6 +8,10 @@ require 'active_record'
8
8
  require 'database_cleaner'
9
9
  require 'factory_girl'
10
10
  require "rack/test"
11
+ require "dm-core"
12
+ require "dm-migrations"
13
+ require "mongo_mapper"
14
+ require "orm_adapter"
11
15
 
12
16
  ENV["RAILS_ENV"] = "test"
13
17
 
@@ -21,11 +25,24 @@ RSpec.configure do |config|
21
25
 
22
26
  load File.dirname(__FILE__) + '/support/schema.rb'
23
27
 
28
+ # Initialize MongoMapper access.
29
+ MongoMapper.connection = Mongo::Connection.new('localhost', 27017)
30
+ MongoMapper.database = "test"
31
+
32
+ # Initialize Mongoid configuration.
33
+
34
+ # Initialize support with DataMapper
35
+ DataMapper.setup(:default, 'sqlite::memory:')
36
+
24
37
 
25
38
  Dir["#{File.dirname(__FILE__)}/support/models/*.rb"].each {|f| require f}
26
39
  Dir["#{File.dirname(__FILE__)}/factories/*.rb"].each {|f| require f }
27
40
  Dir["#{File.dirname(__FILE__)}/support/*.rb"].each{ |f| require f }
28
41
 
42
+ # Finalize models declaration for DataMapper
43
+ DataMapper.finalize
44
+ DataMapper.auto_migrate!
45
+
29
46
  # methods or matchers
30
47
  require 'rspec/expectations'
31
48
  config.include RSpec::Matchers
@@ -68,8 +68,22 @@ class APIExample < Grape::API
68
68
  end
69
69
  end
70
70
 
71
- resource :model do
72
- validate_token in: User, field: :token
71
+ {:model_active_record => User,
72
+ :model_data_mapper => UserDataMapper,
73
+ :model_mongo_mapper => UserMongoMapper
74
+ }.each do |resource_name, model|
75
+
76
+ resource "#{resource_name}" do
77
+ validate_token in: model, field: :token
78
+
79
+ get :something do
80
+ {content: 'secret content'}
81
+ end
82
+ end
83
+ end
84
+
85
+ resource :wrong_model do
86
+ validate_token in: Object, field: :token
73
87
 
74
88
  get :something do
75
89
  {content: 'secret content'}
@@ -83,9 +97,11 @@ class APIExample < Grape::API
83
97
  {content: 'secret content'}
84
98
  end
85
99
  end
86
- # validate_token in: User, field: :auth_token
87
- # validate_token with: do |token|
88
- #
89
- # end
90
100
 
101
+ resource :missing_token_message do
102
+ validate_token is: 'AAA', missing_message: 'API token is missing'
103
+ get :something do
104
+ {content: 'secret content'}
105
+ end
106
+ end
91
107
  end
@@ -1,4 +1,3 @@
1
1
  class User < ActiveRecord::Base
2
2
  validates_presence_of :name
3
-
4
3
  end
@@ -0,0 +1,8 @@
1
+ class UserDataMapper
2
+ include DataMapper::Resource
3
+
4
+ property :id, Serial
5
+ property :name, String
6
+ property :email, String
7
+ property :token, String
8
+ end
@@ -0,0 +1,7 @@
1
+ class UserMongoMapper
2
+ include MongoMapper::Document
3
+
4
+ key :name, String
5
+ key :email, String
6
+ key :token, String
7
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: grape-tokeeo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Antonio Pagano
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-07 00:00:00.000000000 Z
11
+ date: 2015-01-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -136,6 +136,76 @@ dependencies:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: dm-sqlite-adapter
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '1.2'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '1.2'
153
+ - !ruby/object:Gem::Dependency
154
+ name: dm-core
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '1.2'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '1.2'
167
+ - !ruby/object:Gem::Dependency
168
+ name: dm-migrations
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '1.2'
174
+ type: :development
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '1.2'
181
+ - !ruby/object:Gem::Dependency
182
+ name: bson_ext
183
+ requirement: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - "~>"
186
+ - !ruby/object:Gem::Version
187
+ version: '1.0'
188
+ type: :development
189
+ prerelease: false
190
+ version_requirements: !ruby/object:Gem::Requirement
191
+ requirements:
192
+ - - "~>"
193
+ - !ruby/object:Gem::Version
194
+ version: '1.0'
195
+ - !ruby/object:Gem::Dependency
196
+ name: mongo_mapper
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: '0.11'
202
+ type: :development
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - "~>"
207
+ - !ruby/object:Gem::Version
208
+ version: '0.11'
139
209
  - !ruby/object:Gem::Dependency
140
210
  name: grape
141
211
  requirement: !ruby/object:Gem::Requirement
@@ -164,6 +234,20 @@ dependencies:
164
234
  - - "~>"
165
235
  - !ruby/object:Gem::Version
166
236
  version: '4'
237
+ - !ruby/object:Gem::Dependency
238
+ name: orm_adapter
239
+ requirement: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - "~>"
242
+ - !ruby/object:Gem::Version
243
+ version: 0.5.0
244
+ type: :runtime
245
+ prerelease: false
246
+ version_requirements: !ruby/object:Gem::Requirement
247
+ requirements:
248
+ - - "~>"
249
+ - !ruby/object:Gem::Version
250
+ version: 0.5.0
167
251
  description: " Grape resources provides simple API token auth for grape in three different
168
252
  flavours."
169
253
  email:
@@ -187,6 +271,8 @@ files:
187
271
  - spec/spec_helper.rb
188
272
  - spec/support/examples/api_example.rb
189
273
  - spec/support/models/user.rb
274
+ - spec/support/models/user_data_mapper.rb
275
+ - spec/support/models/user_mongo_mapper.rb
190
276
  - spec/support/schema.rb
191
277
  homepage: https://github.com/wawandco/grape-tokeeo
192
278
  licenses:
@@ -219,4 +305,6 @@ test_files:
219
305
  - spec/spec_helper.rb
220
306
  - spec/support/examples/api_example.rb
221
307
  - spec/support/models/user.rb
308
+ - spec/support/models/user_data_mapper.rb
309
+ - spec/support/models/user_mongo_mapper.rb
222
310
  - spec/support/schema.rb