bookingsync-engine 3.0.2 → 4.0.0
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 +4 -4
- data/README.md +101 -5
- data/app/controllers/sessions_controller.rb +1 -1
- data/lib/bookingsync-engine.rb +24 -1
- data/lib/bookingsync/engine.rb +26 -17
- data/lib/bookingsync/engine/application_credentials.rb +15 -0
- data/lib/bookingsync/engine/auth_helpers.rb +5 -2
- data/lib/bookingsync/engine/credentials_resolver.rb +18 -0
- data/lib/bookingsync/engine/models.rb +11 -0
- data/lib/bookingsync/engine/models/account.rb +36 -0
- data/lib/bookingsync/engine/models/application.rb +9 -0
- data/lib/bookingsync/engine/{model.rb → models/base_account.rb} +15 -27
- data/lib/bookingsync/engine/models/multi_applications_account.rb +47 -0
- data/lib/bookingsync/engine/version.rb +1 -1
- data/spec/controllers/authenticated_controller_spec.rb +1 -1
- data/spec/controllers/sessions_controller_spec.rb +28 -4
- data/spec/dummy/app/models/account.rb +1 -1
- data/spec/dummy/app/models/application.rb +3 -0
- data/spec/dummy/app/models/application_record.rb +3 -0
- data/spec/dummy/app/models/multi_applications_account.rb +3 -0
- data/spec/dummy/config/database.yml.docker +11 -0
- data/spec/dummy/config/initializers/bookingsync-engine.rb +3 -0
- data/spec/dummy/db/migrate/20140522110326_create_accounts.rb +1 -1
- data/spec/dummy/db/migrate/20140522110454_add_o_auth_fields_to_accounts.rb +1 -1
- data/spec/dummy/db/migrate/20181130062531_create_multi_applications_accounts.rb +8 -0
- data/spec/dummy/db/migrate/20181130062650_add_o_auth_fields_to_multi_applications_accounts.rb +14 -0
- data/spec/dummy/db/migrate/20181130063056_create_applications.rb +8 -0
- data/spec/dummy/db/migrate/20181130063104_add_credentials_fields_to_applications.rb +10 -0
- data/spec/dummy/db/schema.rb +41 -10
- data/spec/dummy/log/development.log +7423 -16
- data/spec/dummy/log/test.log +62430 -617
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/0A/0AkQ3CITU4KXnU7GsiDQLAWeLkJApWK8LSS1j7wEk2I.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/1M/1MTKfLxlwDryDP9C4ksVeuOF5FekTW5EddfnaJ4ujrA.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/2F/2FjAKNLL-jC6FeYfXsL0M8jItncHQcdDy239KNsTZQs.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/2_/2_hJriYgvh3UGtv5NMhrnkrtfpJlyTuQ4F5jYdVf8sQ.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/3J/3JfiofMyqvbHq3sZznFIDsFS81fHxyAWoCXJLrtrWP4.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/3f/3fwING3B2z9NOnWMwdXFatlVw06vge46KkOWOII0KlU.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/4i/4iLsjcOzC2_Y0hxnbPKuyayJABeUFDSyIh4Ed9OA8Xw.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/50/502uMBbq2ELFXg5u1vtykxQ_whhsdgQnmTwNA96niD0.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/5s/5sm0UHvqondwU5MMfjMuqvLW2WQ6S7ylUf9PNw2uCTc.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/6F/6F2x1Bu3NKSTCTwUS6iCRFhKRT_ntZMzmPIMnVGabK4.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/6g/6gkpMq6BGSOyooWUFJJQCs2k3-tT0WID6Vg4wknhJoM.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8K/8KNXqSB0siJpEjgLM64KpfTgX1FSbkYKxWso4jP9F6U.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Bf/BfiLjztc-8aILuCwNaYiWOika9XKeEiGNJJJK_LCEr4.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/CM/CMaRV8szi0IicAXD33YjDgWpLw468X08ycoS-ndwO5o.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Cc/CcghYxY4f6VUjmyR9LJJi0rYn2LXCdBR9t8Qn4SroL8.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Cj/CjEM6wfYwxY_zG--WNzelIKjC420AU9WpvQLgolQOPM.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Cj/cJJ0QWQg4eJ37I13drpPfSy27rwN7iqiQYPswqRm_Po.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/E2/E2tGPoiGjrMuq9vL-ndjkozskpSFwLcGQXxJf_dl4z0.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/EN/ENHTZiiuQ1cqn16401VaQQBp7b0gwZOA7_I-W5CL5ig.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/EV/EVkLQJ6idLBSbQnkUelhejMxSOql0wh2QbtfKpdJiak.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Gg/Gg6i-z0G_WiBfMUE_gmveurGXQff5_TlQi29HwQcZ-8.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Go/Gohhb2B4rJ5hYmGM-VhZxS5dB_NFtsEAdbP1kTKDUeU.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/IH/IHM0sjf5lujHT6BG1cYKLB0rdqCd1KYYR5SLZkxXi1k.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/NS/NSFU7p8JOb9tHDvG74s3jdRt4ONYZoCTluL3HEsrPxc.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/OX/OXQFRQZ5OA2i3YtnP1fZ96aWeUC3_IIqO4fAMdR9FsM.cache +2 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Oi/OiV2J0lyHQgXCDgtmFPNLE59EbztPsv9MNy05s943Yw.cache +2 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Ps/PsVVU35DPe0tSyJ1zEoiPaaJiwo6NclhO2OKuFSn76A.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/R-/R-onhPbfjYnU6tM9fR0wZkXDSvCLrY5G1wyNCSVmKEs.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/RR/RRXzNBrpSlU0RGhaxTSE_1GoRrV4JkWqF0ZoOf9xtzQ.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Rd/Rd_ZtA5c34XyxDbTpkN8_ZfF1x78s46DbRXLu0jqMgo.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Sm/SmJRxdUchUsyyMi6zvsdwrcRR1hfQ9YeSZNKNM-n5lw.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Su/Sue46_TUXTlImzpNh2bkqDFL5cQ08rCAcaaJqlWI7qg.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/T1/T1lVNy8C6VpxjRsI38DgOfG7yIh3OohPWTNZmJb8CPo.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Z-/Z-P7NJ7vzHin8mjLSAoWJW6FZfd6xwWS3xuoCX0DE40.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Z9/Z9d8_EzLy9N7tx_nHmbmBF5LzFtW_0sik4AH1IFBX0Y.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Ze/ZelUAL6jLQcQiGZUfnAbvuJbU9OAqHiXV_Ccu8lToho.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Zr/Zr7RfTTM_QNQ-7MuSD-M0rF18yH25tCSI9G4H5yYjAQ.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/_S/_SxbUQwhqQU8951QbOA6ZZ41F0d9D-VhhQqUE4BCryQ.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/_o/_okSFa_t7W5YJBZTW7ZitTwnmAFYgJup7tpTYum0Udo.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/aJ/aJ4EkukIrCHlOkA1WpQIasGGosjGkOKvRMsfcNQx1QQ.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/bk/bk_rOYlFWoHkh4HHsvbxeo8rSvDWRX6cCbVlO2VCVNA.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/cO/cOGLhXoKF0BumBbtviyCY1xusm_WMEMhGSWY9qFekRU.cache +2 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/cq/cqMX8l9XlG5jEWd0fWjA7MTlj21d6dzcnhhOq08uFHY.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/cy/cyurAtFfq8D4ORO-aDATDzTKcBumJfgafhOUCbECuMw.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/eO/eOY3YH36a6yvdznpQqACMiI0e1CcTwPiEjUdhRfmm9k.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/f3/f3VckKo5w8mrxeqmzwLfZr7f6sj0dA8xZrFq3GMF0ig.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/fS/fSn1A2ssuKdsdJ-uwH_i8bXBaWmbJd0wHd-Ob6pTPi0.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/gD/gDQJ-WkVLldqzYHKOLkamKeU-sTkDscHqOQawz7a6m4.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/hj/hj8Ir9wcVSy1KYrnWu9bpD24vDhCG3tvt-nKbNxb1Wg.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/jH/jHvwYeln0CEBatCDHIjJMF0vIdmuDmS_eTKNxFhOmlA.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/jU/jUktWNbR4V7n34UAZe7uJpmEofhflF0bVtIO2BgxyJ8.cache +2 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/jb/jb46fu3q3DLQ7TFyiuaXmL_CPF7cQst2RgrF0xVyGtA.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/le/lekrQ_bDFewtYzH2xoA2tovuPzYdoSwnauQ4MgDwb0U.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/m8/m8I0GZ1puWB4hISNebXEGDX3G5QkoSVWHP4SiRvN-3Y.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/mn/mNEeM32MBaqiZ0_N_eheQR9oimoBpmcXRXr5puTAh3o.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/mn/mNaj9zqaawn26kC4FL9ECzN5lkppnwTTQ93MIeJRKZg.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/mn/mnJy7Ei2tJLs8tfmmUHjtWmfk2yfl1opoYG7Deg2bWQ.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/oC/oCsZTGZyV4kH8Y4OeSDUdrwfkJFPzTODZjuBKZB8oGQ.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/oS/oS5JF4El36MylOD0SJtv4YV-fsqNzd89t1IqlBzwYes.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/oY/oYCeXuzhz0IQEBtepScpQ7HlUp5yVleUE6BOLsnhXwA.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/oZ/oZDDUJWB1xgHo4uv_iiUCtutWZ6LeJykII3cNkmd_bA.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/q6/q6BYa32YJF11eGVapO4ouNl6gayPIsARgMavlzZmoi0.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/u-/u-Iidm4zcU2RFkiqJFQkLTBxXuEoF5gCeJM4V5-3Qyc.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/uK/uKpQUG2ys9fKuyfsrw1Payh72LhuIrYJXep13nTbIIc.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/uX/uXHfYanP3WS7whlKHqs0pLBkEQwj_IGbfmktFdHfZ_A.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/v9/v9HWdIdg3uuXOOqxWg8Y6aWxzqbywfxecFSDm5ilUs8.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/w2/w2izaLMTzGRpPOq1R_Yl-0Ma7hm7tej5kSjV9khvFSk.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/x7/x7KkTV3ibfIEysLB_ug5bfmnn2VLV_BldukPR3EoPBk.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/y4/y4-jRuYEQUuCPpXrCIiCC1lgXmW4pm12ZEla-d56noA.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/yW/yWlGtA8E8Li2epEGqbxtvBeb5h0e52XZQ8xKiMXgDOY.cache +1 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/yZ/yZRcLaNBQxCgGewY_IaXZrXG1YmOhr1iSxfZ-4MMK9Y.cache +0 -0
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/zU/zUYxN3uLSvSCpp561lMJSJXPGanKNgxT32rw-w5jpPs.cache +0 -0
- data/spec/dummy/tmp/restart.txt +0 -0
- data/spec/helpers/auth_helpers_spec.rb +42 -0
- data/spec/lib/bookingsync/engine/application_credentials_spec.rb +41 -0
- data/spec/lib/bookingsync/engine/credentials_resolver_spec.rb +18 -0
- data/spec/models/account_spec.rb +130 -41
- data/spec/models/application_spec.rb +16 -0
- data/spec/models/multi_application_account_spec.rb +247 -0
- data/spec/spec_helper.rb +6 -4
- metadata +256 -34
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bafa080b2693177194be61b73fb8fbc32ba466d0
|
|
4
|
+
data.tar.gz: 4c5254207f7fd9dfadb7f843c51e6bb5181b807c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2f823f488456547aecf91ddc065b4b0533961efea5b634516468b2d19bbb14ee2a2c16119624481676576da70411a5896575d1ecccd9cea94cb492cd4f3e6738
|
|
7
|
+
data.tar.gz: 715bba185b33ae77fd182af8ad5b8a0ea851766dc148eb438ffd0f8b22414c8885afdb96469fec08d2c57e8a20a144052a722e86b1e3c87e0cb39538b8c632a4
|
data/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
## Requirements
|
|
7
7
|
|
|
8
|
-
This engine requires Rails `>= 5.0.0` and Ruby `>= 2.
|
|
8
|
+
This engine requires Rails `>= 5.0.0` and Ruby `>= 2.3.0`.
|
|
9
9
|
|
|
10
10
|
## Documentation
|
|
11
11
|
|
|
@@ -36,12 +36,15 @@ This will add the following routes:
|
|
|
36
36
|
* `/auth/failure`
|
|
37
37
|
* `/signout`
|
|
38
38
|
|
|
39
|
+
|
|
39
40
|
BookingSync Engine uses the `Account` model to authenticate each BookingSync Account, if you do not have an `Account` model yet, create one:
|
|
40
41
|
|
|
41
42
|
```console
|
|
42
43
|
rails g model Account
|
|
43
44
|
```
|
|
44
45
|
|
|
46
|
+
### For single application setup
|
|
47
|
+
|
|
45
48
|
Then, generate a migration to add OAuth fields for the `Account` class:
|
|
46
49
|
|
|
47
50
|
```console
|
|
@@ -56,15 +59,100 @@ and migrate:
|
|
|
56
59
|
rake db:migrate
|
|
57
60
|
```
|
|
58
61
|
|
|
59
|
-
Also include `BookingSync::Engine::Account` in your `Account` model:
|
|
62
|
+
Also include `BookingSync::Engine::Models::Account` in your `Account` model:
|
|
63
|
+
|
|
64
|
+
```ruby
|
|
65
|
+
class Account < ActiveRecord::Base
|
|
66
|
+
include BookingSync::Engine::Models::Account
|
|
67
|
+
end
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### For multi application setup
|
|
71
|
+
|
|
72
|
+
Then, generate a migration to add OAuth fields for the `Account` class:
|
|
73
|
+
|
|
74
|
+
```console
|
|
75
|
+
rails g migration AddOAuthFieldsToAccounts provider:string synced_id:integer:index \
|
|
76
|
+
name:string oauth_access_token:string oauth_refresh_token:string \
|
|
77
|
+
oauth_expires_at:string host:string:uniq:index
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Add manually `null: false` to the `host` field on the newly created migration file, then migrate:
|
|
81
|
+
|
|
82
|
+
```console
|
|
83
|
+
rake db:migrate
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Also include `BookingSync::Engine::Models::MultiApplicationsAccount` in your `Account` model:
|
|
60
87
|
|
|
61
88
|
```ruby
|
|
62
89
|
class Account < ActiveRecord::Base
|
|
63
|
-
include BookingSync::Engine::
|
|
90
|
+
include BookingSync::Engine::Models::MultiApplicationsAccount
|
|
91
|
+
end
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
You also need to create applications
|
|
95
|
+
|
|
96
|
+
```console
|
|
97
|
+
rails g model Application
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Then, generate a migration to add credentials fields for the `Application` class:
|
|
101
|
+
|
|
102
|
+
```console
|
|
103
|
+
rails g migration AddCredentialsFieldsToApplications host:string:uniq:index client_id:text:uniq:index \
|
|
104
|
+
client_secret:text:uniq:index
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Add `null: false` to this 3 attributes, then migrate:
|
|
108
|
+
|
|
109
|
+
```console
|
|
110
|
+
rake db:migrate
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Also include `BookingSync::Engine::Models::Application` in your `Application` model:
|
|
114
|
+
|
|
115
|
+
```ruby
|
|
116
|
+
class Application < ActiveRecord::Base
|
|
117
|
+
include BookingSync::Engine::Models::Application
|
|
118
|
+
end
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Activate the multi app mode in an initializer:
|
|
122
|
+
|
|
123
|
+
```ruby
|
|
124
|
+
BookingSyncEngine.setup do |setup|
|
|
125
|
+
setup.support_multi_applications = true
|
|
126
|
+
end
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
#### Use different models for single app and multiple app setup
|
|
130
|
+
|
|
131
|
+
To make transition between the two modes on the fly, you can use different model name for your
|
|
132
|
+
accounts.
|
|
133
|
+
|
|
134
|
+
For the following example:
|
|
135
|
+
|
|
136
|
+
```ruby
|
|
137
|
+
class MySingleAppAccount < ActiveRecord::Base
|
|
138
|
+
include BookingSync::Engine::Models::Account
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
class MyMultiAppAccount < ActiveRecord::Base
|
|
142
|
+
include BookingSync::Engine::Models::MultiApplicationsAccount
|
|
143
|
+
end
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
You just need to define which model goes with which mode in an initializer.
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
```ruby
|
|
150
|
+
BookingSyncEngine.setup do |setup|
|
|
151
|
+
setup.single_app_model = -> { ::MySingleAppAccount }
|
|
152
|
+
setup.multi_app_model = -> { ::MyMultiAppAccount }
|
|
64
153
|
end
|
|
65
154
|
```
|
|
66
155
|
|
|
67
|
-
When saving new token, this gem uses a separate thread with new db connection to ensure token save (in case of a rollback in the main transaction). To make room for the new connections, it is recommended to increase db `pool` size by 2-3.
|
|
68
156
|
|
|
69
157
|
## Configuration
|
|
70
158
|
|
|
@@ -77,7 +165,7 @@ The engine is configured by the following ENV variables:
|
|
|
77
165
|
* `BOOKINGSYNC_SCOPE` - Space separated list of required scopes. Defaults to nil, which means the public scope.
|
|
78
166
|
|
|
79
167
|
You might want to use [dotenv-rails](https://github.com/bkeepers/dotenv)
|
|
80
|
-
to make ENV variables management easy.
|
|
168
|
+
to make ENV variables management easy. See `spec/dummy/.env.sample`.
|
|
81
169
|
|
|
82
170
|
## Embedded vs Standalone apps
|
|
83
171
|
|
|
@@ -168,3 +256,11 @@ We would love to see you contributing. Please, just follow the guidelines from [
|
|
|
168
256
|
### Testing
|
|
169
257
|
|
|
170
258
|
By default, your tests will run against the Rails version used in the main Gemfile.lock, to test against all supported Rails version, please run the tests with Appraisals with: `appraisal rake spec`
|
|
259
|
+
|
|
260
|
+
#### Testing with docker
|
|
261
|
+
|
|
262
|
+
You can choose to run PostgreSQL in a Docker container. At the moment, you should use [Beta channel](https://docs.docker.com/docker-for-mac/) on a Mac - so you can reach the docker machine on localhost. It is possible to set it up with stable, but then you have to configure it another way.
|
|
263
|
+
|
|
264
|
+
Use `spec/dummy/config/database.yml.docker` instead of `spec/dummy/config/database.yml`.
|
|
265
|
+
|
|
266
|
+
Once intalled, setup the DB with `docker-compose create`, `docker-compose start` and `rake db:setup`
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
class SessionsController < ApplicationController
|
|
2
2
|
def create
|
|
3
3
|
auth = request.env["omniauth.auth"]
|
|
4
|
-
account =
|
|
4
|
+
account = BookingSyncEngine.account_model.from_omniauth(auth, request.host)
|
|
5
5
|
account_authorized(account)
|
|
6
6
|
redirect_to after_bookingsync_sign_in_path
|
|
7
7
|
end
|
data/lib/bookingsync-engine.rb
CHANGED
|
@@ -1 +1,24 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "bookingsync"
|
|
2
|
+
|
|
3
|
+
module BookingSyncEngine
|
|
4
|
+
cattr_accessor :support_multi_applications
|
|
5
|
+
self.support_multi_applications = false
|
|
6
|
+
|
|
7
|
+
cattr_accessor :single_app_model
|
|
8
|
+
self.single_app_model = -> { ::Account }
|
|
9
|
+
|
|
10
|
+
cattr_accessor :multi_app_model
|
|
11
|
+
self.multi_app_model = -> { ::Account }
|
|
12
|
+
|
|
13
|
+
def self.setup
|
|
14
|
+
yield self
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.support_multi_applications?
|
|
18
|
+
support_multi_applications
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.account_model
|
|
22
|
+
support_multi_applications? ? multi_app_model.call : single_app_model.call
|
|
23
|
+
end
|
|
24
|
+
end
|
data/lib/bookingsync/engine.rb
CHANGED
|
@@ -1,22 +1,30 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
3
|
-
require
|
|
1
|
+
require "omniauth"
|
|
2
|
+
require "omniauth-bookingsync"
|
|
3
|
+
require "bookingsync-api"
|
|
4
4
|
|
|
5
5
|
module BookingSync
|
|
6
6
|
class Engine < ::Rails::Engine
|
|
7
7
|
initializer "bookingsync.add_omniauth" do |app|
|
|
8
8
|
app.middleware.use OmniAuth::Builder do
|
|
9
9
|
provider :bookingsync,
|
|
10
|
-
ENV[
|
|
11
|
-
ENV[
|
|
12
|
-
scope: ENV[
|
|
10
|
+
BookingSyncEngine.support_multi_applications? ? nil : ENV["BOOKINGSYNC_APP_ID"],
|
|
11
|
+
BookingSyncEngine.support_multi_applications? ? nil : ENV["BOOKINGSYNC_APP_SECRET"],
|
|
12
|
+
scope: ENV["BOOKINGSYNC_SCOPE"],
|
|
13
13
|
setup: -> (env) {
|
|
14
|
-
if url = ENV[
|
|
15
|
-
env[
|
|
14
|
+
if url = ENV["BOOKINGSYNC_URL"]
|
|
15
|
+
env["omniauth.strategy"].options[:client_options].site = url
|
|
16
16
|
end
|
|
17
|
-
env[
|
|
18
|
-
verify: ENV[
|
|
17
|
+
env["omniauth.strategy"].options[:client_options].ssl = {
|
|
18
|
+
verify: ENV["BOOKINGSYNC_VERIFY_SSL"] != "false"
|
|
19
19
|
}
|
|
20
|
+
|
|
21
|
+
if BookingSyncEngine.support_multi_applications?
|
|
22
|
+
credentials = BookingSync::Engine::CredentialsResolver.new(env["HTTP_HOST"]).call
|
|
23
|
+
if credentials.valid?
|
|
24
|
+
env["omniauth.strategy"].options[:client_id] = credentials.client_id
|
|
25
|
+
env["omniauth.strategy"].options[:client_secret] = credentials.client_secret
|
|
26
|
+
end
|
|
27
|
+
end
|
|
20
28
|
}
|
|
21
29
|
end
|
|
22
30
|
end
|
|
@@ -67,21 +75,22 @@ module BookingSync
|
|
|
67
75
|
# The ENV variables used for configuration are described in {file:README.md}.
|
|
68
76
|
#
|
|
69
77
|
# @return [OAuth2::Client] configured OAuth client
|
|
70
|
-
def self.oauth_client
|
|
78
|
+
def self.oauth_client(client_id: ENV["BOOKINGSYNC_APP_ID"], client_secret: ENV["BOOKINGSYNC_APP_SECRET"])
|
|
71
79
|
client_options = {
|
|
72
|
-
site: ENV[
|
|
80
|
+
site: ENV["BOOKINGSYNC_URL"] || 'https://www.bookingsync.com',
|
|
73
81
|
connection_opts: { headers: { accept: "application/vnd.api+json" } }
|
|
74
82
|
}
|
|
75
83
|
client_options[:ssl] = { verify: ENV['BOOKINGSYNC_VERIFY_SSL'] != 'false' }
|
|
76
|
-
OAuth2::Client.new(
|
|
77
|
-
client_options)
|
|
84
|
+
OAuth2::Client.new(client_id, client_secret, client_options)
|
|
78
85
|
end
|
|
79
86
|
|
|
80
|
-
def self.application_token
|
|
81
|
-
oauth_client.client_credentials.get_token
|
|
87
|
+
def self.application_token(client_id: ENV["BOOKINGSYNC_APP_ID"], client_secret: ENV["BOOKINGSYNC_APP_SECRET"])
|
|
88
|
+
oauth_client(client_id: client_id, client_secret: client_secret).client_credentials.get_token
|
|
82
89
|
end
|
|
83
90
|
end
|
|
84
91
|
end
|
|
85
92
|
|
|
93
|
+
require "bookingsync/engine/application_credentials"
|
|
94
|
+
require "bookingsync/engine/credentials_resolver"
|
|
86
95
|
require "bookingsync/engine/api_client"
|
|
87
|
-
require "bookingsync/engine/
|
|
96
|
+
require "bookingsync/engine/models"
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
class BookingSync::Engine::ApplicationCredentials
|
|
2
|
+
attr_reader :client_id
|
|
3
|
+
attr_reader :client_secret
|
|
4
|
+
|
|
5
|
+
def initialize(application = nil)
|
|
6
|
+
if application.present?
|
|
7
|
+
@client_id = application.client_id
|
|
8
|
+
@client_secret = application.client_secret
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def valid?
|
|
13
|
+
client_id.present? && client_secret.present?
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -11,7 +11,10 @@ module BookingSync::Engine::AuthHelpers
|
|
|
11
11
|
|
|
12
12
|
# @return [Account, nil] currently authorized Account or nil if unauthorized
|
|
13
13
|
def current_account
|
|
14
|
-
|
|
14
|
+
return if session[:account_id].nil?
|
|
15
|
+
|
|
16
|
+
@current_account ||=
|
|
17
|
+
BookingSyncEngine.account_model.find_by_host_and_synced_id(request.host, session[:account_id])
|
|
15
18
|
end
|
|
16
19
|
|
|
17
20
|
# Callback after account is authorized.
|
|
@@ -130,7 +133,7 @@ module BookingSync::Engine::AuthHelpers
|
|
|
130
133
|
store_bookingsync_account_id if BookingSync::Engine.embedded
|
|
131
134
|
sign_out_if_inactive
|
|
132
135
|
enforce_requested_account_authorized!
|
|
133
|
-
request_authorization!
|
|
136
|
+
request_authorization! if current_account.nil?
|
|
134
137
|
end
|
|
135
138
|
|
|
136
139
|
def store_bookingsync_account_id # :nodoc:
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
class BookingSync::Engine::CredentialsResolver
|
|
2
|
+
attr_reader :host
|
|
3
|
+
private :host
|
|
4
|
+
|
|
5
|
+
def initialize(host)
|
|
6
|
+
@host = host
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def call
|
|
10
|
+
BookingSync::Engine::ApplicationCredentials.new(application)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
private
|
|
14
|
+
|
|
15
|
+
def application
|
|
16
|
+
@application ||= ::Application.find_by_host(host)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module BookingSync
|
|
2
|
+
class Engine
|
|
3
|
+
module Models
|
|
4
|
+
end
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
require "bookingsync/engine/models/base_account"
|
|
9
|
+
require "bookingsync/engine/models/account"
|
|
10
|
+
require "bookingsync/engine/models/multi_applications_account"
|
|
11
|
+
require "bookingsync/engine/models/application"
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module BookingSync::Engine::Models::Account
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
include BookingSync::Engine::Models::BaseAccount
|
|
4
|
+
|
|
5
|
+
included do
|
|
6
|
+
validates :synced_id, uniqueness: true
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
module ClassMethods
|
|
10
|
+
def from_omniauth(auth, _host)
|
|
11
|
+
account = find_or_initialize_by(synced_id: auth.uid, provider: auth.provider)
|
|
12
|
+
|
|
13
|
+
account.tap do |account|
|
|
14
|
+
account.name = auth.info.business_name
|
|
15
|
+
account.update_token(auth.credentials)
|
|
16
|
+
account.save!
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def find_by_host_and_synced_id(_host, synced_id)
|
|
21
|
+
find_by(synced_id: synced_id)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def application_token
|
|
26
|
+
BookingSync::Engine.application_token
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def oauth_client
|
|
30
|
+
BookingSync::Engine.oauth_client
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def application
|
|
34
|
+
nil
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
module BookingSync::Engine::Models::Application
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
included do
|
|
5
|
+
validates :host, presence: true, uniqueness: true
|
|
6
|
+
validates :client_id, presence: true, uniqueness: true
|
|
7
|
+
validates :client_secret, presence: true, uniqueness: true
|
|
8
|
+
end
|
|
9
|
+
end
|
|
@@ -1,21 +1,10 @@
|
|
|
1
|
-
module BookingSync::Engine::
|
|
1
|
+
module BookingSync::Engine::Models::BaseAccount
|
|
2
2
|
extend ActiveSupport::Concern
|
|
3
3
|
|
|
4
4
|
included do
|
|
5
|
-
validates :synced_id, uniqueness: true
|
|
6
5
|
scope :authorized, -> { where.not(oauth_access_token: nil) }
|
|
7
6
|
end
|
|
8
7
|
|
|
9
|
-
module ClassMethods
|
|
10
|
-
def from_omniauth(auth)
|
|
11
|
-
find_or_initialize_by(synced_id: auth.uid, provider: auth.provider).tap do |account|
|
|
12
|
-
account.name = auth.info.business_name
|
|
13
|
-
account.update_token(auth.credentials)
|
|
14
|
-
account.save!
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
|
|
19
8
|
def token
|
|
20
9
|
@token ||= begin
|
|
21
10
|
token_options = {}
|
|
@@ -24,8 +13,7 @@ module BookingSync::Engine::Model
|
|
|
24
13
|
token_options[:expires_at] = oauth_expires_at
|
|
25
14
|
end
|
|
26
15
|
|
|
27
|
-
token = OAuth2::AccessToken.new(
|
|
28
|
-
oauth_access_token, token_options)
|
|
16
|
+
token = OAuth2::AccessToken.new(oauth_client, oauth_access_token, token_options)
|
|
29
17
|
|
|
30
18
|
if token.expired?
|
|
31
19
|
refresh_token!(token)
|
|
@@ -35,29 +23,29 @@ module BookingSync::Engine::Model
|
|
|
35
23
|
end
|
|
36
24
|
end
|
|
37
25
|
|
|
38
|
-
def refresh_token!(current_token = token)
|
|
39
|
-
@token = current_token.refresh!.tap { |new_token| update_token!(new_token) }
|
|
40
|
-
end
|
|
41
|
-
|
|
42
26
|
def api
|
|
43
27
|
@api ||= BookingSync::Engine::APIClient.new(token.token, account: self)
|
|
44
28
|
end
|
|
45
29
|
|
|
30
|
+
def clear_token!
|
|
31
|
+
self.oauth_access_token = nil
|
|
32
|
+
self.oauth_refresh_token = nil
|
|
33
|
+
self.oauth_expires_at = nil
|
|
34
|
+
save!
|
|
35
|
+
end
|
|
36
|
+
|
|
46
37
|
def update_token(token)
|
|
47
38
|
self.oauth_access_token = token.token
|
|
48
39
|
self.oauth_refresh_token = token.refresh_token
|
|
49
40
|
self.oauth_expires_at = token.expires_at
|
|
50
41
|
end
|
|
51
42
|
|
|
52
|
-
|
|
53
|
-
update_token(token)
|
|
54
|
-
save!
|
|
55
|
-
end
|
|
43
|
+
private
|
|
56
44
|
|
|
57
|
-
def
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
45
|
+
def refresh_token!(current_token = token)
|
|
46
|
+
@token = current_token.refresh!.tap do |new_token|
|
|
47
|
+
update_token(new_token)
|
|
48
|
+
save!
|
|
49
|
+
end
|
|
62
50
|
end
|
|
63
51
|
end
|