solidus_identifiers 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +35 -0
  3. data/.gem_release.yml +5 -0
  4. data/.github/stale.yml +17 -0
  5. data/.gitignore +21 -0
  6. data/.gitlab/ci.yml +63 -0
  7. data/.rspec +2 -0
  8. data/.rubocop.yml +17 -0
  9. data/Gemfile +33 -0
  10. data/LICENSE +26 -0
  11. data/README.md +396 -0
  12. data/Rakefile +6 -0
  13. data/app/decorators/solidus_identifiers/spree/api/api_helpers_decorator.rb +20 -0
  14. data/app/decorators/solidus_identifiers/spree/permission_sets/user_management_decorator.rb +15 -0
  15. data/app/decorators/solidus_identifiers/spree/permitted_attributes_decorator.rb +16 -0
  16. data/app/decorators/solidus_identifiers/spree/user_decorator.rb +11 -0
  17. data/app/models/spree/identifier.rb +19 -0
  18. data/app/models/spree/identifier_key.rb +17 -0
  19. data/app/views/spree/api/identifier_keys/_identifier_key.json.jbuilder +5 -0
  20. data/app/views/spree/api/identifier_keys/index.json.jbuilder +6 -0
  21. data/app/views/spree/api/identifier_keys/show.json.jbuilder +3 -0
  22. data/app/views/spree/api/identifiers/_identifier.json.jbuilder +14 -0
  23. data/app/views/spree/api/identifiers/index.json.jbuilder +6 -0
  24. data/app/views/spree/api/identifiers/show.json.jbuilder +3 -0
  25. data/app/views/spree/api/users/_user.json.jbuilder +31 -0
  26. data/bin/console +17 -0
  27. data/bin/r +15 -0
  28. data/bin/rake +7 -0
  29. data/bin/sandbox +84 -0
  30. data/bin/sandbox_rails +18 -0
  31. data/bin/setup +8 -0
  32. data/config/locales/en.yml +5 -0
  33. data/config/routes.rb +9 -0
  34. data/db/migrate/20200603191551_create_spree_identifier_keys.rb +10 -0
  35. data/db/migrate/20200603191555_create_spree_identifiers.rb +18 -0
  36. data/db/migrate/20200603203105_add_unique_index_to_spree_identifier_keys.rb +7 -0
  37. data/lib/controllers/api/spree/api/identifier_keys_controller.rb +15 -0
  38. data/lib/controllers/api/spree/api/identifiers_controller.rb +15 -0
  39. data/lib/generators/solidus_identifiers/install/install_generator.rb +26 -0
  40. data/lib/solidus_identifiers.rb +7 -0
  41. data/lib/solidus_identifiers/engine.rb +19 -0
  42. data/lib/solidus_identifiers/factories.rb +14 -0
  43. data/lib/solidus_identifiers/version.rb +5 -0
  44. data/solidus_identifiers.gemspec +38 -0
  45. data/spec/controllers/spree/api/identifier_keys_controller_spec.rb +151 -0
  46. data/spec/controllers/spree/api/identifiers_controller_spec.rb +161 -0
  47. data/spec/models/spree/identifier_key_spec.rb +21 -0
  48. data/spec/models/spree/identifier_spec.rb +33 -0
  49. data/spec/spec_helper.rb +32 -0
  50. metadata +174 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: '0170823488af18e57ed09e826fad553f200549e564728c3ebecf7beb72425c07'
4
+ data.tar.gz: fd69cb5668dee36fcd26e893573d9b4f6af8ad5210cac2f8a53cead71de2ddfa
5
+ SHA512:
6
+ metadata.gz: 7badff5c06e5abc81d0fdcbb164d0a949de3856c0876272b7d96b226b045f725df79af73e3a69979c7e057b357cd5fdedcb573d42710e6e2c0b9a4f3cea853f3
7
+ data.tar.gz: fad42bcc10e9d681192666225a75d7e0a8e29d4cc21e481dd3adfa9466dab64a2e1a28fdc97d826294225f79b60708aa072f015ddac7d0106fb44eefe2568b4b
@@ -0,0 +1,35 @@
1
+ version: 2.1
2
+
3
+ orbs:
4
+ # Always take the latest version of the orb, this allows us to
5
+ # run specs against Solidus supported versions only without the need
6
+ # to change this configuration every time a Solidus version is released
7
+ # or goes EOL.
8
+ solidusio_extensions: solidusio/extensions@volatile
9
+
10
+ jobs:
11
+ run-specs-with-postgres:
12
+ executor: solidusio_extensions/postgres
13
+ steps:
14
+ - solidusio_extensions/run-tests
15
+ run-specs-with-mysql:
16
+ executor: solidusio_extensions/mysql
17
+ steps:
18
+ - solidusio_extensions/run-tests
19
+
20
+ workflows:
21
+ "Run specs on supported Solidus versions":
22
+ jobs:
23
+ - run-specs-with-postgres
24
+ - run-specs-with-mysql
25
+ "Weekly run specs against master":
26
+ triggers:
27
+ - schedule:
28
+ cron: "0 0 * * 4" # every Thursday
29
+ filters:
30
+ branches:
31
+ only:
32
+ - master
33
+ jobs:
34
+ - run-specs-with-postgres
35
+ - run-specs-with-mysql
@@ -0,0 +1,5 @@
1
+ bump:
2
+ recurse: false
3
+ file: 'lib/solidus_identifiers/version.rb'
4
+ message: Bump SolidusIdentifiers to %{version}
5
+ tag: true
@@ -0,0 +1,17 @@
1
+ # Number of days of inactivity before an issue becomes stale
2
+ daysUntilStale: 60
3
+ # Number of days of inactivity before a stale issue is closed
4
+ daysUntilClose: 7
5
+ # Issues with these labels will never be considered stale
6
+ exemptLabels:
7
+ - pinned
8
+ - security
9
+ # Label to use when marking an issue as stale
10
+ staleLabel: wontfix
11
+ # Comment to post when marking an issue as stale. Set to `false` to disable
12
+ markComment: >
13
+ This issue has been automatically marked as stale because it has not had
14
+ recent activity. It will be closed if no further activity occurs. Thank you
15
+ for your contributions.
16
+ # Comment to post when closing a stale issue. Set to `false` to disable
17
+ closeComment: false
@@ -0,0 +1,21 @@
1
+ *.gem
2
+ \#*
3
+ *~
4
+ .#*
5
+ .DS_Store
6
+ .idea
7
+ .project
8
+ .sass-cache
9
+ coverage
10
+ Gemfile.lock
11
+ tmp
12
+ nbproject
13
+ pkg
14
+ *.swp
15
+ spec/dummy
16
+ spec/examples.txt
17
+ /sandbox
18
+ .rvmrc
19
+ .ruby-version
20
+ .ruby-gemset
21
+ .byebug_history
@@ -0,0 +1,63 @@
1
+ image: ruby:latest
2
+
3
+ stages:
4
+ - test
5
+
6
+ cache:
7
+ paths:
8
+ - vendor/ruby
9
+
10
+ variables:
11
+ DATABASE_CLEANER_ALLOW_REMOTE_DATABASE_URL: 'true'
12
+ DATABASE_URL: postgres://runner@postgres:5432/gitlab-test
13
+ DB: postgresql
14
+ POSTGRES_HOST: postgres
15
+ POSTGRES_USER: runner
16
+ POSTGRES_PASSWORD: ""
17
+ POSTGRES_HOST_AUTH_METHOD: trust
18
+ RAILS_ENV: test
19
+
20
+ before_script:
21
+ - curl -sL https://deb.nodesource.com/setup_10.x | bash -
22
+ - curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
23
+ - echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
24
+ - apt-get update
25
+ - apt-get install -qy yarn
26
+
27
+ - ruby -v # Print out ruby version for debugging
28
+ - gem install bundler --no-document # Bundler is not installed with the image
29
+ - bundle config set path 'vendor/ruby'
30
+ - bundle install -j $(nproc) # Install dependencies into ./vendor/ruby
31
+
32
+ .rspec:
33
+ stage: test
34
+ services:
35
+ - postgres:latest
36
+ script:
37
+ - echo "Running specs for ${SOLIDUS_BRANCH}"
38
+ - bundle exec rake
39
+
40
+ rubocop:
41
+ script:
42
+ - bundle exec rubocop
43
+
44
+ rspec:solidus-master:
45
+ extends: .rspec
46
+ variables:
47
+ SOLIDUS_BRANCH: master
48
+
49
+ rspec:solidus-v2.10:
50
+ extends: .rspec
51
+ variables:
52
+ SOLIDUS_BRANCH: v2.10
53
+
54
+ rspec:solidus-v2.9:
55
+ extends: .rspec
56
+ variables:
57
+ SOLIDUS_BRANCH: v2.9
58
+
59
+ rspec:solidus-v2.8:
60
+ extends: .rspec
61
+ variables:
62
+ SOLIDUS_BRANCH: v2.8
63
+
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -0,0 +1,17 @@
1
+ require:
2
+ - solidus_dev_support/rubocop
3
+
4
+ AllCops:
5
+ Exclude:
6
+ - sandbox/**/*
7
+ - spec/dummy/**/*
8
+ - vendor/**/*
9
+
10
+ Style/ClassVars:
11
+ Enabled: false
12
+
13
+ Style/FrozenStringLiteralComment:
14
+ Enabled: false
15
+
16
+ RSpec/MultipleExpectations:
17
+ Enabled: false
data/Gemfile ADDED
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
5
+
6
+ branch = ENV.fetch('SOLIDUS_BRANCH', 'master')
7
+ gem 'solidus', github: 'solidusio/solidus', branch: branch
8
+
9
+ # Needed to help Bundler figure out how to resolve dependencies,
10
+ # otherwise it takes forever to resolve them.
11
+ # See https://github.com/bundler/bundler/issues/6677
12
+ gem 'rails', '>0.a'
13
+
14
+ # Provides basic authentication functionality for testing parts of your engine
15
+ gem 'solidus_auth_devise'
16
+
17
+ case ENV['DB']
18
+ when 'mysql'
19
+ gem 'mysql2'
20
+ when 'postgresql'
21
+ gem 'pg'
22
+ else
23
+ gem 'sqlite3'
24
+ end
25
+
26
+ gemspec
27
+
28
+ # Use a local Gemfile to include development dependencies that might not be
29
+ # relevant for the project or for other contributors, e.g. pry-byebug.
30
+ #
31
+ # We use `send` instead of calling `eval_gemfile` to work around an issue with
32
+ # how Dependabot parses projects: https://github.com/dependabot/dependabot-core/issues/1658.
33
+ send(:eval_gemfile, 'Gemfile-local') if File.exist? 'Gemfile-local'
data/LICENSE ADDED
@@ -0,0 +1,26 @@
1
+ Copyright (c) 2020 [name of plugin creator]
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification,
5
+ are permitted provided that the following conditions are met:
6
+
7
+ * Redistributions of source code must retain the above copyright notice,
8
+ this list of conditions and the following disclaimer.
9
+ * Redistributions in binary form must reproduce the above copyright notice,
10
+ this list of conditions and the following disclaimer in the documentation
11
+ and/or other materials provided with the distribution.
12
+ * Neither the name Solidus nor the names of its contributors may be used to
13
+ endorse or promote products derived from this software without specific
14
+ prior written permission.
15
+
16
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,396 @@
1
+ SolidusIdentifiers
2
+ ==================
3
+
4
+ Welcome to solidus identifiers. This is a simple gem for managing 3rd party identifier for user, products etc.
5
+ The identifiers are polymorphic so they can be applied to any record.
6
+
7
+ Installation
8
+ ------------
9
+
10
+ Add solidus_identifiers to your Gemfile:
11
+
12
+ ```ruby
13
+ gem 'solidus_identifiers'
14
+ ```
15
+
16
+ Bundle your dependencies and run the installation generator:
17
+
18
+ ```shell
19
+ bundle
20
+ bundle exec rails g solidus_identifiers:install
21
+ ```
22
+
23
+ Usage
24
+ -----
25
+
26
+ **Create a Key**
27
+
28
+ Keys are unique by name
29
+
30
+ ```ruby
31
+ Spree::IdentifierKey.create! name: 'facebook-uuid'
32
+ Spree::IdentifierKey.create! name: 'google-uuid'
33
+ Spree::IdentifierKey.create! name: 'twitter-uuid'
34
+ Spree::IdentifierKey.create! name: 'braintree-customer-id'
35
+ Spree::IdentifierKey.create! name: 'stripe-customer-id'
36
+
37
+ Spree::IdentifierKey.create! name: 'stripe-customer-id'
38
+ #=> Error! ActiveRecord::RecordNotUnique
39
+ ```
40
+
41
+ **Create an Identifier**
42
+
43
+ Identifiers are unique by a composite key of `(key, attachable_id, attachable_type)`.
44
+ For example, a user can only have one identifier of a specific key.
45
+
46
+ ```ruby
47
+ user = Spree::User.find(10)
48
+ key = Spree::IdentifierKey.find_by(name: 'facebook-uuid')
49
+
50
+ identifier = Spree::Identifier.create!(attachable: user, key: key, value: 'xxxx-xxxx-xxxx')
51
+ identifier.attachable == user
52
+ #=> true
53
+
54
+ user.reload
55
+ user.identifiers
56
+ #=> [<Spree::Identifier xxx>]
57
+
58
+ Spree::Identifier.create!(attachable: user, key: key, value: 'yyyy-yyyy-yyyy')
59
+ #=> Error! ActiveRecord::RecordNotUnique
60
+ ```
61
+
62
+ **Note**
63
+
64
+ Identifiers are polymorphic however right now only the `Spree::User` has an association back to the
65
+ `Spree::Identifier`. If you'd like to add an association from another class you can do something like:
66
+
67
+ ```ruby
68
+ module ProductDecorator
69
+ def self.prepended(base)
70
+ base.has_many :identifiers, as: :attachable
71
+ end
72
+
73
+ ::Spree.Product.prepend(self)
74
+ end
75
+
76
+ product = Spree::Product.first
77
+ product.identifiers
78
+ ```
79
+
80
+ API
81
+ ---
82
+
83
+ ### Identifier Keys
84
+
85
+ #### Get all Keys
86
+
87
+ **Header Parameters**
88
+
89
+ | Name | Type | Required | Description |
90
+ | ------------- | ------ | -------- | -------------------------- |
91
+ | Authorization | string | required | The spree api key |
92
+ | Content-Type | string | required | Must be `application/json` |
93
+
94
+ **Query Parameters**
95
+
96
+ None
97
+
98
+ **Body Parameters**
99
+
100
+ None
101
+
102
+ **Request**
103
+
104
+ `GET /api/identifier_keys`
105
+
106
+ ```json
107
+ {}
108
+ ```
109
+
110
+ **Response**
111
+
112
+ ```json
113
+ {
114
+ "count": 1,
115
+ "total_count": 1,
116
+ "current_page": 1,
117
+ "pages": 1,
118
+ "per_page": 25,
119
+ "identifier_keys": [
120
+ {
121
+ "id": 1,
122
+ "name": "facebook-uuid"
123
+ },
124
+ {
125
+ "id": 2,
126
+ "name": "google-uuid"
127
+ }
128
+ ]
129
+ }
130
+ ```
131
+
132
+ #### Create an Identifier Key
133
+
134
+ **Header Parameters**
135
+
136
+ | Name | Type | Required | Description |
137
+ | ------------- | ------ | -------- | -------------------------- |
138
+ | Authorization | string | required | The spree api key |
139
+ | Content-Type | string | required | Must be `application/json` |
140
+
141
+ **Query Parameters**
142
+
143
+ None
144
+
145
+ **Body Parameters**
146
+
147
+ | Name | Type | Required | Description |
148
+ | -------------- | ------------- | -------- | ------------------------- |
149
+ | identifier_key | IdentifierKey | required | The identifier key object |
150
+
151
+ **IdentifierKey Parameters**
152
+
153
+ | Name | Type | Required | Description |
154
+ | ---- | ------ | -------- | -------------------- |
155
+ | name | string | required | The name for the key |
156
+
157
+ **Request**
158
+
159
+ `GET /api/identifier_keys`
160
+
161
+ ```json
162
+ {
163
+ "identifier_key": {
164
+ "name": "google-uuid"
165
+ }
166
+ }
167
+ ```
168
+
169
+ **Response**
170
+
171
+ ```json
172
+ {
173
+ "id": 2,
174
+ "name": "google-uuid"
175
+ }
176
+ ```
177
+
178
+ ### Identifiers
179
+
180
+ #### Get all identifiers
181
+
182
+ **Header Parameters**
183
+
184
+ | Name | Type | Required | Description |
185
+ | ------------- | ------ | -------- | -------------------------- |
186
+ | Authorization | string | required | The spree api key |
187
+ | Content-Type | string | required | Must be `application/json` |
188
+
189
+ **Query Parameters**
190
+
191
+ None
192
+
193
+ **Body Parameters**
194
+
195
+ None
196
+
197
+ **Request**
198
+
199
+ `GET /api/identifiers`
200
+
201
+ ```json
202
+ {}
203
+ ```
204
+
205
+ **Response**
206
+
207
+ ```json
208
+ {
209
+ "count": 2,
210
+ "total_count": 2,
211
+ "current_page": 1,
212
+ "pages": 1,
213
+ "per_page": 25,
214
+ "identifiers": [
215
+ {
216
+ "id": 1,
217
+ "value": "1111-2222-3333",
218
+ "key": {
219
+ "id": 1,
220
+ "name": "facebook-uuid"
221
+ },
222
+ "attachable": {
223
+ "id": 1,
224
+ "type": "Spree::User"
225
+ }
226
+ },
227
+ {
228
+ "id": 2,
229
+ "value": "1234-1234-1234",
230
+ "key": {
231
+ "id": 2,
232
+ "name": "google-uuid"
233
+ },
234
+ "attachable": {
235
+ "id": 1,
236
+ "type": "Spree::User"
237
+ }
238
+ }
239
+ ]
240
+ }
241
+ ```
242
+
243
+ #### Get single identifier
244
+
245
+ **Header Parameters**
246
+
247
+ | Name | Type | Required | Description |
248
+ | ------------- | ------ | -------- | -------------------------- |
249
+ | Authorization | string | required | The spree api key |
250
+ | Content-Type | string | required | Must be `application/json` |
251
+
252
+ **Query Parameters**
253
+
254
+ | Name | Type | Required | Description |
255
+ | ---- | ------- | -------- | ------------------------ |
256
+ | id | integer | required | The id of the identifier |
257
+
258
+ **Body Parameters**
259
+
260
+ None
261
+
262
+ **Request**
263
+
264
+ `GET /api/identifiers/{id}`
265
+
266
+ ```json
267
+ {}
268
+ ```
269
+
270
+ **Response**
271
+
272
+ ```json
273
+ {
274
+ "id": 1,
275
+ "value": "1111-2222-3333",
276
+ "key": {
277
+ "id": 1,
278
+ "name": "facebook-uuid"
279
+ },
280
+ "attachable": {
281
+ "id": 1,
282
+ "type": "Spree::User"
283
+ }
284
+ }
285
+ ```
286
+
287
+ #### Create an Identifier
288
+
289
+ **Header Parameters**
290
+
291
+ | Name | Type | Required | Description |
292
+ | ------------- | ------ | -------- | -------------------------- |
293
+ | Authorization | string | required | The spree api key |
294
+ | Content-Type | string | required | Must be `application/json` |
295
+
296
+ **Query Parameters**
297
+
298
+ None
299
+
300
+ **Body Parameters**
301
+
302
+ | Name | Type | Required | Description |
303
+ | --------------- | ------- | -------- | ------------------------------------- |
304
+ | key_id | integer | required | The id of the Identifier Key |
305
+ | attachable_id | integer | required | The id of the attachable record |
306
+ | attachable_type | string | required | The type of the attachable record |
307
+ | value | string | required | The value to assign to the identifier |
308
+
309
+ **Identifier Parameters**
310
+
311
+ | Name | Type | Required | Description |
312
+ | ---- | ------ | -------- | -------------------- |
313
+ | name | string | required | The name for the key |
314
+
315
+ **Request**
316
+
317
+ `POST /api/identifiers`
318
+
319
+ ```json
320
+ {
321
+ "identifier": {
322
+ "key_id": "2",
323
+ "value": "1234-1234-1234",
324
+ "attachable_type": "Spree::User",
325
+ "attachable_id": 1,
326
+ }
327
+ }
328
+ ```
329
+
330
+ **Response**
331
+
332
+ ```json
333
+ {
334
+ "id": 2,
335
+ "value": "1234-1234-1234",
336
+ "key": {
337
+ "id": 2,
338
+ "name": "google-uuid"
339
+ },
340
+ "attachable": {
341
+ "id": 1,
342
+ "type": "Spree::User"
343
+ }
344
+ }
345
+ ```
346
+
347
+ Testing/Developing
348
+ -------
349
+
350
+ First bundle your dependencies, then run `bin/rake`. `bin/rake` will default to building the dummy app if it does not exist, then it will run specs. The dummy app can be regenerated by using `bin/rake extension:test_app`.
351
+
352
+ ```shell
353
+ bundle
354
+ bin/rake
355
+ ```
356
+
357
+ To run [Rubocop](https://github.com/bbatsov/rubocop) static code analysis run
358
+
359
+ ```shell
360
+ bundle exec rubocop
361
+ ```
362
+
363
+ When testing your application's integration with this extension you may use its factories.
364
+ Simply add this require statement to your spec_helper:
365
+
366
+ ```ruby
367
+ require 'solidus_identifiers/factories'
368
+ ```
369
+
370
+ Sandbox app
371
+ -----------
372
+
373
+ To run this extension in a sandboxed Solidus application you can run `bin/sandbox`
374
+ The path for the sandbox app is `./sandbox` and `bin/rails` will forward any Rails command
375
+ to `sandbox/bin/rails`.
376
+
377
+ Example:
378
+
379
+ ```shell
380
+ $ bin/rails server
381
+ => Booting Puma
382
+ => Rails 6.0.2.1 application starting in development
383
+ * Listening on tcp://127.0.0.1:3000
384
+ Use Ctrl-C to stop
385
+ ```
386
+
387
+ Releasing
388
+ ---------
389
+
390
+ Your new extension version can be released using `gem-release` like this:
391
+
392
+ ```shell
393
+ bundle exec gem bump -v VERSION --tag --push --remote upstream && gem release
394
+ ```
395
+
396
+ Copyright (c) 2020 [name of extension creator], released under the New BSD License