bookingsync-engine 4.0.1 → 6.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 +5 -5
- data/app/views/sessions/failure.html.erb +3 -1
- data/lib/bookingsync-engine.rb +11 -2
- data/lib/bookingsync/engine.rb +14 -5
- data/lib/bookingsync/engine/auth_helpers.rb +38 -16
- data/lib/bookingsync/engine/models/account.rb +9 -3
- data/lib/bookingsync/engine/models/base_account.rb +8 -6
- data/lib/bookingsync/engine/models/multi_applications_account.rb +9 -3
- data/lib/bookingsync/engine/retryable.rb +16 -0
- data/lib/bookingsync/engine/version.rb +1 -1
- data/spec/controllers/authenticated_controller_spec.rb +36 -12
- data/spec/dummy/app/assets/config/manifest.js +3 -0
- data/spec/dummy/config/initializers/bookingsync-engine.rb +8 -0
- data/spec/dummy/db/migrate/20190623220013_add_custom_booking_sync_key_id_to_accounts.rb +5 -0
- data/spec/dummy/db/migrate/20190623220132_add_custom_booking_sync_key_id_to_multi_applications_accounts.rb +5 -0
- data/spec/dummy/db/schema.rb +3 -1
- data/spec/dummy/log/development.log +2 -7427
- data/spec/dummy/log/test.log +9640 -62357
- data/spec/fixtures/accounts.yml +2 -0
- data/spec/lib/bookingsync/engine/retryable_spec.rb +81 -0
- data/spec/models/account_spec.rb +79 -0
- data/spec/models/multi_application_account_spec.rb +12 -0
- metadata +43 -153
- 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 +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/2_/2_hJriYgvh3UGtv5NMhrnkrtfpJlyTuQ4F5jYdVf8sQ.cache +0 -1
- 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 +0 -1
- 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 +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/6F/6F2x1Bu3NKSTCTwUS6iCRFhKRT_ntZMzmPIMnVGabK4.cache +0 -1
- 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 +0 -1
- 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 +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/EV/EVkLQJ6idLBSbQnkUelhejMxSOql0wh2QbtfKpdJiak.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Gg/Gg6i-z0G_WiBfMUE_gmveurGXQff5_TlQi29HwQcZ-8.cache +0 -1
- 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 +0 -1
- 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 +0 -2
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Oi/OiV2J0lyHQgXCDgtmFPNLE59EbztPsv9MNy05s943Yw.cache +0 -2
- 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 +0 -1
- 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 +0 -1
- 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 +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Ze/ZelUAL6jLQcQiGZUfnAbvuJbU9OAqHiXV_Ccu8lToho.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Zr/Zr7RfTTM_QNQ-7MuSD-M0rF18yH25tCSI9G4H5yYjAQ.cache +0 -1
- 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 +0 -1
- 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 +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/cO/cOGLhXoKF0BumBbtviyCY1xusm_WMEMhGSWY9qFekRU.cache +0 -2
- 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 +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/fS/fSn1A2ssuKdsdJ-uwH_i8bXBaWmbJd0wHd-Ob6pTPi0.cache +0 -1
- 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 +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/jU/jUktWNbR4V7n34UAZe7uJpmEofhflF0bVtIO2BgxyJ8.cache +0 -2
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/jb/jb46fu3q3DLQ7TFyiuaXmL_CPF7cQst2RgrF0xVyGtA.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/le/lekrQ_bDFewtYzH2xoA2tovuPzYdoSwnauQ4MgDwb0U.cache +0 -1
- 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 +0 -1
- 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 +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/oY/oYCeXuzhz0IQEBtepScpQ7HlUp5yVleUE6BOLsnhXwA.cache +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/oZ/oZDDUJWB1xgHo4uv_iiUCtutWZ6LeJykII3cNkmd_bA.cache +0 -1
- 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 +0 -1
- 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 +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/w2/w2izaLMTzGRpPOq1R_Yl-0Ma7hm7tej5kSjV9khvFSk.cache +0 -1
- 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 +0 -1
- data/spec/dummy/tmp/cache/assets/sprockets/v3.0/yW/yWlGtA8E8Li2epEGqbxtvBeb5h0e52XZQ8xKiMXgDOY.cache +0 -1
- 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
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 76d677891a37b6bf242cc2ecdccac253d00e74d980c4c674f1e4e258a23c27aa
|
|
4
|
+
data.tar.gz: 6bbe344b51c76817b5f91e5db0196a8ff651a8ed668c15e8c24f809357fe7568
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0105eb59ada39b9121ad1aad63e72f7c8f9d1d717ef9cfa85ad5189b9aedf06aa61bc165265289ca55e783546ce2713f720fe26d900116b3cbe5f9d84a921587
|
|
7
|
+
data.tar.gz: 850bbffb9e6233f2c15009073a463ecfed670bb46db08a5b62afd5abdd8dcb5df0eee57f580872a1603cc84f897dcd4997d2d7e09c8361b384d63a2535b54640
|
data/lib/bookingsync-engine.rb
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
require "bookingsync"
|
|
2
|
-
|
|
3
1
|
module BookingSyncEngine
|
|
4
2
|
cattr_accessor :support_multi_applications
|
|
5
3
|
self.support_multi_applications = false
|
|
@@ -10,6 +8,15 @@ module BookingSyncEngine
|
|
|
10
8
|
cattr_accessor :multi_app_model
|
|
11
9
|
self.multi_app_model = -> { ::Account }
|
|
12
10
|
|
|
11
|
+
cattr_accessor :oauth_client_connection_options
|
|
12
|
+
self.oauth_client_connection_options = { request: { timeout: 2 } }
|
|
13
|
+
|
|
14
|
+
cattr_accessor :token_refresh_timeout_retry_count
|
|
15
|
+
self.token_refresh_timeout_retry_count = 2
|
|
16
|
+
|
|
17
|
+
cattr_accessor :bookingsync_id_key
|
|
18
|
+
self.bookingsync_id_key = :synced_id
|
|
19
|
+
|
|
13
20
|
def self.setup
|
|
14
21
|
yield self
|
|
15
22
|
end
|
|
@@ -22,3 +29,5 @@ module BookingSyncEngine
|
|
|
22
29
|
support_multi_applications? ? multi_app_model.call : single_app_model.call
|
|
23
30
|
end
|
|
24
31
|
end
|
|
32
|
+
|
|
33
|
+
require "bookingsync"
|
data/lib/bookingsync/engine.rb
CHANGED
|
@@ -7,8 +7,8 @@ module BookingSync
|
|
|
7
7
|
initializer "bookingsync.add_omniauth" do |app|
|
|
8
8
|
app.middleware.use OmniAuth::Builder do
|
|
9
9
|
provider :bookingsync,
|
|
10
|
-
BookingSyncEngine.support_multi_applications? ? nil : ENV["BOOKINGSYNC_APP_ID"],
|
|
11
|
-
BookingSyncEngine.support_multi_applications? ? nil : ENV["BOOKINGSYNC_APP_SECRET"],
|
|
10
|
+
::BookingSyncEngine.support_multi_applications? ? nil : ENV["BOOKINGSYNC_APP_ID"],
|
|
11
|
+
::BookingSyncEngine.support_multi_applications? ? nil : ENV["BOOKINGSYNC_APP_SECRET"],
|
|
12
12
|
scope: ENV["BOOKINGSYNC_SCOPE"],
|
|
13
13
|
setup: -> (env) {
|
|
14
14
|
if url = ENV["BOOKINGSYNC_URL"]
|
|
@@ -18,7 +18,7 @@ module BookingSync
|
|
|
18
18
|
verify: ENV["BOOKINGSYNC_VERIFY_SSL"] != "false"
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
if BookingSyncEngine.support_multi_applications?
|
|
21
|
+
if ::BookingSyncEngine.support_multi_applications?
|
|
22
22
|
credentials = BookingSync::Engine::CredentialsResolver.new(env["HTTP_HOST"]).call
|
|
23
23
|
if credentials.valid?
|
|
24
24
|
env["omniauth.strategy"].options[:client_id] = credentials.client_id
|
|
@@ -76,16 +76,24 @@ module BookingSync
|
|
|
76
76
|
#
|
|
77
77
|
# @return [OAuth2::Client] configured OAuth client
|
|
78
78
|
def self.oauth_client(client_id: ENV["BOOKINGSYNC_APP_ID"], client_secret: ENV["BOOKINGSYNC_APP_SECRET"])
|
|
79
|
+
connection_options = {
|
|
80
|
+
headers: { accept: "application/vnd.api+json" }
|
|
81
|
+
}.merge(::BookingSyncEngine.oauth_client_connection_options)
|
|
82
|
+
|
|
79
83
|
client_options = {
|
|
80
84
|
site: ENV["BOOKINGSYNC_URL"] || 'https://www.bookingsync.com',
|
|
81
|
-
connection_opts:
|
|
85
|
+
connection_opts: connection_options
|
|
82
86
|
}
|
|
83
87
|
client_options[:ssl] = { verify: ENV['BOOKINGSYNC_VERIFY_SSL'] != 'false' }
|
|
84
88
|
OAuth2::Client.new(client_id, client_secret, client_options)
|
|
85
89
|
end
|
|
86
90
|
|
|
87
91
|
def self.application_token(client_id: ENV["BOOKINGSYNC_APP_ID"], client_secret: ENV["BOOKINGSYNC_APP_SECRET"])
|
|
88
|
-
|
|
92
|
+
token_refresh_timeout_attempts_allowed = ::BookingSyncEngine.token_refresh_timeout_retry_count + 1
|
|
93
|
+
|
|
94
|
+
BookingSync::Engine::Retryable.perform(times: token_refresh_timeout_attempts_allowed, errors: [Faraday::TimeoutError]) do
|
|
95
|
+
oauth_client(client_id: client_id, client_secret: client_secret).client_credentials.get_token
|
|
96
|
+
end
|
|
89
97
|
end
|
|
90
98
|
end
|
|
91
99
|
end
|
|
@@ -94,3 +102,4 @@ require "bookingsync/engine/application_credentials"
|
|
|
94
102
|
require "bookingsync/engine/credentials_resolver"
|
|
95
103
|
require "bookingsync/engine/api_client"
|
|
96
104
|
require "bookingsync/engine/models"
|
|
105
|
+
require "bookingsync/engine/retryable"
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require "repost"
|
|
2
|
+
|
|
1
3
|
module BookingSync::Engine::AuthHelpers
|
|
2
4
|
extend ActiveSupport::Concern
|
|
3
5
|
|
|
@@ -16,7 +18,7 @@ module BookingSync::Engine::AuthHelpers
|
|
|
16
18
|
return if session[:account_id].nil?
|
|
17
19
|
|
|
18
20
|
@current_account ||=
|
|
19
|
-
BookingSyncEngine.account_model.
|
|
21
|
+
::BookingSyncEngine.account_model.find_by_host_and_bookingsync_id_key(request.host, session[:account_id])
|
|
20
22
|
end
|
|
21
23
|
|
|
22
24
|
# Callback after account is authorized.
|
|
@@ -25,7 +27,7 @@ module BookingSync::Engine::AuthHelpers
|
|
|
25
27
|
#
|
|
26
28
|
# @param account [Account] the just authorized account
|
|
27
29
|
def account_authorized(account)
|
|
28
|
-
session[:account_id] = account.
|
|
30
|
+
session[:account_id] = account.public_send(BookingSyncEngine.bookingsync_id_key).to_s
|
|
29
31
|
end
|
|
30
32
|
|
|
31
33
|
# Clear authorization if the account passed from the BookingSync app store
|
|
@@ -58,20 +60,32 @@ module BookingSync::Engine::AuthHelpers
|
|
|
58
60
|
|
|
59
61
|
# Request a new authorization.
|
|
60
62
|
def request_authorization!
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
respond_to do |format|
|
|
64
|
+
format.html do
|
|
65
|
+
if request.xhr?
|
|
66
|
+
request_authorization_for_xhr!
|
|
67
|
+
elsif BookingSync::Engine.embedded
|
|
68
|
+
request_authorization_for_embedded!
|
|
69
|
+
else
|
|
70
|
+
request_authorization_for_standalone!
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
format.json do
|
|
75
|
+
head :unauthorized
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
format.api_json do
|
|
79
|
+
head :unauthorized
|
|
80
|
+
end
|
|
67
81
|
end
|
|
68
82
|
end
|
|
69
83
|
|
|
70
84
|
# Request a new authorization for Ajax requests.
|
|
71
85
|
#
|
|
72
|
-
# Renders the new
|
|
86
|
+
# Renders the new auto submit form with 401 Unauthorized status by default.
|
|
73
87
|
def request_authorization_for_xhr!
|
|
74
|
-
render
|
|
88
|
+
render html: auto_submit_form_html, status: :unauthorized
|
|
75
89
|
end
|
|
76
90
|
|
|
77
91
|
# Request a new authorization for Embedded Apps.
|
|
@@ -79,23 +93,23 @@ module BookingSync::Engine::AuthHelpers
|
|
|
79
93
|
# Load the new authorization path using Javascript by default.
|
|
80
94
|
def request_authorization_for_embedded!
|
|
81
95
|
allow_bookingsync_iframe
|
|
82
|
-
render html:
|
|
83
|
-
"'#{new_authorization_path}';</script>").html_safe
|
|
96
|
+
render html: auto_submit_form_html
|
|
84
97
|
end
|
|
85
98
|
|
|
86
99
|
# Request a new authorization for Standalone Apps.
|
|
87
100
|
#
|
|
88
101
|
# Redirects to new authorization path by default.
|
|
89
102
|
def request_authorization_for_standalone!
|
|
90
|
-
|
|
103
|
+
render html: auto_submit_form_html
|
|
91
104
|
end
|
|
92
105
|
|
|
93
|
-
# Path
|
|
106
|
+
# Path which will be used in POST request to start a new
|
|
94
107
|
# Authorization process.
|
|
95
108
|
#
|
|
96
|
-
# Default to /auth/bookingsync
|
|
109
|
+
# Default to /auth/bookingsync
|
|
110
|
+
NEW_AUTHORIZATION_URL = "/auth/bookingsync".freeze
|
|
97
111
|
def new_authorization_path
|
|
98
|
-
|
|
112
|
+
NEW_AUTHORIZATION_URL
|
|
99
113
|
end
|
|
100
114
|
|
|
101
115
|
def new_authorization_url
|
|
@@ -141,4 +155,12 @@ module BookingSync::Engine::AuthHelpers
|
|
|
141
155
|
def store_bookingsync_account_id # :nodoc:
|
|
142
156
|
session[:_bookingsync_account_id] = params.delete(:_bookingsync_account_id)
|
|
143
157
|
end
|
|
158
|
+
|
|
159
|
+
def auto_submit_form_html
|
|
160
|
+
Repost::Senpai.perform(
|
|
161
|
+
new_authorization_path,
|
|
162
|
+
params: { account_id: session[:_bookingsync_account_id] },
|
|
163
|
+
options: { authenticity_token: Rack::Protection::AuthenticityToken.token(session) }
|
|
164
|
+
).html_safe
|
|
165
|
+
end
|
|
144
166
|
end
|
|
@@ -3,12 +3,12 @@ module BookingSync::Engine::Models::Account
|
|
|
3
3
|
include BookingSync::Engine::Models::BaseAccount
|
|
4
4
|
|
|
5
5
|
included do
|
|
6
|
-
validates
|
|
6
|
+
validates BookingSyncEngine.bookingsync_id_key, uniqueness: true
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
module ClassMethods
|
|
10
10
|
def from_omniauth(auth, _host)
|
|
11
|
-
account = find_or_initialize_by(
|
|
11
|
+
account = find_or_initialize_by(BookingSyncEngine.bookingsync_id_key => auth.uid, provider: auth.provider)
|
|
12
12
|
|
|
13
13
|
account.tap do |account|
|
|
14
14
|
account.name = auth.info.business_name
|
|
@@ -17,8 +17,14 @@ module BookingSync::Engine::Models::Account
|
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
+
def find_by_host_and_bookingsync_id_key(_host, bookingsync_id)
|
|
21
|
+
find_by(BookingSyncEngine.bookingsync_id_key => bookingsync_id)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# DEPRECATED: Please use find_by_host_and_bookingsync_id_key instead.
|
|
20
25
|
def find_by_host_and_synced_id(_host, synced_id)
|
|
21
|
-
|
|
26
|
+
warn("DEPRECATED: find_by_host_and_synced_id is deprecated, use #find_by_host_and_bookingsync_id_key instead. It will be removed with the release of version 6 of this gem. Called from #{Gem.location_of_caller.join(":")}")
|
|
27
|
+
find_by_host_and_bookingsync_id_key(nil, synced_id)
|
|
22
28
|
end
|
|
23
29
|
end
|
|
24
30
|
|
|
@@ -10,7 +10,7 @@ module BookingSync::Engine::Models::BaseAccount
|
|
|
10
10
|
token_options = {}
|
|
11
11
|
if oauth_refresh_token
|
|
12
12
|
token_options[:refresh_token] = oauth_refresh_token
|
|
13
|
-
token_options[:expires_at] = oauth_expires_at
|
|
13
|
+
token_options[:expires_at] = oauth_expires_at && oauth_expires_at.to_i
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
token = OAuth2::AccessToken.new(oauth_client, oauth_access_token, token_options)
|
|
@@ -40,12 +40,14 @@ module BookingSync::Engine::Models::BaseAccount
|
|
|
40
40
|
self.oauth_expires_at = token.expires_at
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
-
private
|
|
44
|
-
|
|
45
43
|
def refresh_token!(current_token = token)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
token_refresh_timeout_attempts_allowed = ::BookingSyncEngine.token_refresh_timeout_retry_count + 1
|
|
45
|
+
|
|
46
|
+
BookingSync::Engine::Retryable.perform(times: token_refresh_timeout_attempts_allowed, errors: [Faraday::TimeoutError]) do
|
|
47
|
+
@token = current_token.refresh!.tap do |new_token|
|
|
48
|
+
update_token(new_token)
|
|
49
|
+
save!
|
|
50
|
+
end
|
|
49
51
|
end
|
|
50
52
|
end
|
|
51
53
|
end
|
|
@@ -3,7 +3,7 @@ module BookingSync::Engine::Models::MultiApplicationsAccount
|
|
|
3
3
|
include BookingSync::Engine::Models::BaseAccount
|
|
4
4
|
|
|
5
5
|
included do
|
|
6
|
-
validates
|
|
6
|
+
validates BookingSyncEngine.bookingsync_id_key, uniqueness: { scope: :host }
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
module ClassMethods
|
|
@@ -13,7 +13,7 @@ module BookingSync::Engine::Models::MultiApplicationsAccount
|
|
|
13
13
|
"multi application support"
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
account = find_or_initialize_by(host: host,
|
|
16
|
+
account = find_or_initialize_by(host: host, provider: auth.provider, BookingSyncEngine.bookingsync_id_key => auth.uid)
|
|
17
17
|
|
|
18
18
|
account.tap do |account|
|
|
19
19
|
account.name = auth.info.business_name
|
|
@@ -22,8 +22,14 @@ module BookingSync::Engine::Models::MultiApplicationsAccount
|
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
def find_by_host_and_bookingsync_id_key(host, bookingsync_id)
|
|
26
|
+
find_by(host: host, BookingSyncEngine.bookingsync_id_key => bookingsync_id)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# DEPRECATED: Please use find_by_host_and_bookingsync_id_key instead.
|
|
25
30
|
def find_by_host_and_synced_id(host, synced_id)
|
|
26
|
-
|
|
31
|
+
warn("DEPRECATED: find_by_host_and_synced_id is deprecated, use #find_by_host_and_bookingsync_id_key instead. It will be removed with the release of version 5 of this gem. Called from #{Gem.location_of_caller.join(":")}")
|
|
32
|
+
find_by_host_and_bookingsync_id_key(host, synced_id)
|
|
27
33
|
end
|
|
28
34
|
end
|
|
29
35
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
class BookingSync::Engine::Retryable
|
|
2
|
+
def self.perform(times:, errors:, before_retry: ->(_error) {})
|
|
3
|
+
executed = 0
|
|
4
|
+
begin
|
|
5
|
+
executed += 1
|
|
6
|
+
yield
|
|
7
|
+
rescue *errors => error
|
|
8
|
+
if executed < times
|
|
9
|
+
before_retry.call(error)
|
|
10
|
+
retry
|
|
11
|
+
else
|
|
12
|
+
raise error
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
require "spec_helper"
|
|
2
2
|
|
|
3
3
|
RSpec.describe AuthenticatedController, type: :controller do
|
|
4
|
+
before do
|
|
5
|
+
Mime::Type.register "application/vnd.api+json", :api_json
|
|
6
|
+
end
|
|
7
|
+
|
|
4
8
|
describe "GET index" do
|
|
5
9
|
context "when engine is embedded" do
|
|
6
10
|
before { BookingSync::Engine.embedded! }
|
|
7
11
|
|
|
8
|
-
it "
|
|
12
|
+
it "renders autosubmitted form" do
|
|
9
13
|
get :index
|
|
10
14
|
expect(response.status).to eq(200)
|
|
11
|
-
expect(response.body).to
|
|
12
|
-
|
|
15
|
+
expect(response.body).to include("action='/auth/bookingsync' method='post'")
|
|
16
|
+
expect(response.body).to include("<input type='hidden' name='account_id' value=''>")
|
|
13
17
|
expect(response.header["Content-Type"]).to include("text/html")
|
|
14
18
|
end
|
|
15
19
|
end
|
|
@@ -17,12 +21,11 @@ RSpec.describe AuthenticatedController, type: :controller do
|
|
|
17
21
|
context "when engine is standalone" do
|
|
18
22
|
before { BookingSync::Engine.standalone! }
|
|
19
23
|
|
|
20
|
-
it "
|
|
24
|
+
it "renders autosubmitted form" do
|
|
21
25
|
get :index
|
|
22
|
-
expect(response.status).to eq(
|
|
23
|
-
expect(response.
|
|
24
|
-
expect(response.body).to
|
|
25
|
-
"<html><body>You are being <a href=\"http://test.host/auth/bookingsync/?account_id=\">redirected</a>.</body></html>")
|
|
26
|
+
expect(response.status).to eq(200)
|
|
27
|
+
expect(response.body).to include("action='/auth/bookingsync' method='post'")
|
|
28
|
+
expect(response.body).to include("<input type='hidden' name='account_id' value=''>")
|
|
26
29
|
end
|
|
27
30
|
end
|
|
28
31
|
end
|
|
@@ -31,20 +34,41 @@ RSpec.describe AuthenticatedController, type: :controller do
|
|
|
31
34
|
context "when engine is embedded" do
|
|
32
35
|
before { BookingSync::Engine.embedded! }
|
|
33
36
|
|
|
34
|
-
it "renders
|
|
37
|
+
it "renders autosubmitted form" do
|
|
35
38
|
get :index, xhr: true
|
|
36
39
|
expect(response.status).to eq(401)
|
|
37
|
-
expect(response.body).to
|
|
40
|
+
expect(response.body).to include("action='/auth/bookingsync' method='post'")
|
|
41
|
+
expect(response.body).to include("<input type='hidden' name='account_id' value=''>")
|
|
38
42
|
end
|
|
39
43
|
end
|
|
40
44
|
|
|
41
45
|
context "when engine is standalone" do
|
|
42
46
|
before { BookingSync::Engine.standalone! }
|
|
43
47
|
|
|
44
|
-
it "renders
|
|
48
|
+
it "renders autosubmitted form" do
|
|
45
49
|
get :index, xhr: true
|
|
46
50
|
expect(response.status).to eq(401)
|
|
47
|
-
expect(response.body).to
|
|
51
|
+
expect(response.body).to include("action='/auth/bookingsync' method='post'")
|
|
52
|
+
expect(response.body).to include("<input type='hidden' name='account_id' value=''>")
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
describe "API request" do
|
|
58
|
+
it "returns 401 without response body" do
|
|
59
|
+
get :index, format: :json
|
|
60
|
+
expect(response.status).to eq(401)
|
|
61
|
+
expect(response.body).to eq("")
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
context "with vnd.api+json content type" do
|
|
65
|
+
it "returns 401 without response body" do
|
|
66
|
+
request.headers["CONTENT_TYPE"] = "application/vnd.api+json"
|
|
67
|
+
request.headers["ACCEPT"] = "application/vnd.api+json"
|
|
68
|
+
|
|
69
|
+
get :index
|
|
70
|
+
expect(response.status).to eq(401)
|
|
71
|
+
expect(response.body).to eq("")
|
|
48
72
|
end
|
|
49
73
|
end
|
|
50
74
|
end
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
# temporarily change default to make sure initializer override works great
|
|
2
|
+
BookingSyncEngine.module_eval do
|
|
3
|
+
self.bookingsync_id_key = :customized_key
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
# and now override to fix breaking specs
|
|
1
7
|
BookingSyncEngine.setup do |setup|
|
|
2
8
|
setup.multi_app_model = -> { ::MultiApplicationsAccount }
|
|
9
|
+
|
|
10
|
+
setup.bookingsync_id_key = :synced_id
|
|
3
11
|
end
|
data/spec/dummy/db/schema.rb
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
#
|
|
11
11
|
# It's strongly recommended that you check this file into your version control system.
|
|
12
12
|
|
|
13
|
-
ActiveRecord::Schema.define(version:
|
|
13
|
+
ActiveRecord::Schema.define(version: 2019_06_23_220132) do
|
|
14
14
|
|
|
15
15
|
# These are extensions that must be enabled in order to support this database
|
|
16
16
|
enable_extension "plpgsql"
|
|
@@ -24,6 +24,7 @@ ActiveRecord::Schema.define(version: 2018_11_30_063104) do
|
|
|
24
24
|
t.string "oauth_access_token"
|
|
25
25
|
t.string "oauth_refresh_token"
|
|
26
26
|
t.string "oauth_expires_at"
|
|
27
|
+
t.integer "customized_key"
|
|
27
28
|
t.index ["synced_id"], name: "index_accounts_on_synced_id"
|
|
28
29
|
end
|
|
29
30
|
|
|
@@ -48,6 +49,7 @@ ActiveRecord::Schema.define(version: 2018_11_30_063104) do
|
|
|
48
49
|
t.string "oauth_refresh_token"
|
|
49
50
|
t.string "oauth_expires_at"
|
|
50
51
|
t.string "host", null: false
|
|
52
|
+
t.integer "customized_key"
|
|
51
53
|
t.index ["host", "synced_id"], name: "index_multi_applications_accounts_on_host_and_synced_id", unique: true
|
|
52
54
|
t.index ["host"], name: "index_multi_applications_accounts_on_host"
|
|
53
55
|
t.index ["synced_id"], name: "index_multi_applications_accounts_on_synced_id"
|