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