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