bookingsync-engine 0.1.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 +7 -0
- data/MIT-LICENSE +20 -0
- data/Rakefile +31 -0
- data/app/controllers/sessions_controller.rb +18 -0
- data/app/views/sessions/failure.html.erb +5 -0
- data/config/routes.rb +5 -0
- data/lib/bookingsync.rb +4 -0
- data/lib/bookingsync/engine.rb +88 -0
- data/lib/bookingsync/engine/auth_helpers.rb +103 -0
- data/lib/bookingsync/engine/helpers.rb +15 -0
- data/lib/bookingsync/engine/model.rb +59 -0
- data/lib/bookingsync/engine/session_helpers.rb +18 -0
- data/lib/bookingsync/engine/token_helpers.rb +31 -0
- data/lib/bookingsync/engine/version.rb +3 -0
- data/lib/generators/bookingsync/install/install_generator.rb +16 -0
- data/lib/generators/bookingsync/install/templates/create_bookingsync_accounts.rb +14 -0
- data/spec/controllers/sessions_controller_spec.rb +57 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/authenticated_controller.rb +6 -0
- data/spec/dummy/app/controllers/home_controller.rb +4 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/models/account.rb +3 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +23 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +17 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +29 -0
- data/spec/dummy/config/environments/production.rb +80 -0
- data/spec/dummy/config/environments/test.rb +36 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +12 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +4 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/migrate/20140522110326_create_accounts.rb +8 -0
- data/spec/dummy/db/migrate/20140522110454_add_o_auth_fields_to_accounts.rb +11 -0
- data/spec/dummy/db/schema.rb +29 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/log/development.log +47 -0
- data/spec/dummy/log/newrelic_agent.log +21 -0
- data/spec/dummy/log/test.log +3080 -0
- data/spec/dummy/public/404.html +58 -0
- data/spec/dummy/public/422.html +58 -0
- data/spec/dummy/public/500.html +57 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/fixtures/accounts.yml +17 -0
- data/spec/models/account_spec.rb +54 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/support/omniauth.rb +13 -0
- metadata +237 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 148999512eaa0db2fb982dd0d359fb5650f48f44
|
|
4
|
+
data.tar.gz: 821ee7611331e250f0c0d4f2a9f6bc4334f8bec2
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: e6c2439872589f7bac7801dd61b28e13c4f33e7e5c57e516a3c40f90e2a593e8c22d07ac59bed9d489d3a09b7b7d295593005f6fdcffd3a9c4f39b45964e8391
|
|
7
|
+
data.tar.gz: 9cdd1bf10710164feedf35b0fb9a0ffea02109b87be78e049fd243be7025c510a54e2ea20c98fb76244a07dfefae1391da77f6f75fae9ef74e9c4a0c94c8efbd
|
data/MIT-LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright 2014 YOURNAME
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
4
|
+
a copy of this software and associated documentation files (the
|
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
9
|
+
the following conditions:
|
|
10
|
+
|
|
11
|
+
The above copyright notice and this permission notice shall be
|
|
12
|
+
included in all copies or substantial portions of the Software.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
begin
|
|
2
|
+
require 'bundler/setup'
|
|
3
|
+
rescue LoadError
|
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
require 'rdoc/task'
|
|
8
|
+
require 'thor'
|
|
9
|
+
|
|
10
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
|
11
|
+
rdoc.rdoc_dir = 'rdoc'
|
|
12
|
+
rdoc.title = 'BookingSync'
|
|
13
|
+
rdoc.options << '--line-numbers'
|
|
14
|
+
rdoc.rdoc_files.include('README.rdoc')
|
|
15
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
|
|
19
|
+
load 'rails/tasks/engine.rake'
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
Bundler::GemHelper.install_tasks
|
|
24
|
+
|
|
25
|
+
require 'rspec/core'
|
|
26
|
+
require 'rspec/core/rake_task'
|
|
27
|
+
|
|
28
|
+
desc "Run all specs in spec directory (excluding plugin specs)"
|
|
29
|
+
RSpec::Core::RakeTask.new(:spec => 'app:db:test:prepare')
|
|
30
|
+
|
|
31
|
+
task default: :spec
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
class SessionsController < ApplicationController
|
|
2
|
+
def create
|
|
3
|
+
auth = request.env["omniauth.auth"]
|
|
4
|
+
account = ::Account.from_omniauth(auth)
|
|
5
|
+
account_authorized(account)
|
|
6
|
+
redirect_to after_bookingsync_sign_in_path
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def destroy
|
|
10
|
+
clear_authorization!
|
|
11
|
+
redirect_to after_bookingsync_sign_out_path
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def failure
|
|
15
|
+
allow_bookingsync_iframe
|
|
16
|
+
@error_message = params[:message].try(:humanize)
|
|
17
|
+
end
|
|
18
|
+
end
|
data/config/routes.rb
ADDED
data/lib/bookingsync.rb
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
require 'omniauth'
|
|
2
|
+
require 'omniauth-bookingsync'
|
|
3
|
+
require 'bookingsync-api'
|
|
4
|
+
|
|
5
|
+
module BookingSync
|
|
6
|
+
class Engine < ::Rails::Engine
|
|
7
|
+
initializer "bookingsync.add_omniauth" do |app|
|
|
8
|
+
app.middleware.use OmniAuth::Builder do
|
|
9
|
+
provider :bookingsync,
|
|
10
|
+
ENV['BOOKINGSYNC_APP_ID'],
|
|
11
|
+
ENV['BOOKINGSYNC_APP_SECRET'],
|
|
12
|
+
scope: ENV['BOOKINGSYNC_SCOPE'],
|
|
13
|
+
setup: -> (env) {
|
|
14
|
+
if url = ENV['BOOKINGSYNC_URL']
|
|
15
|
+
env['omniauth.strategy'].options[:client_options].site = url
|
|
16
|
+
end
|
|
17
|
+
env['omniauth.strategy'].options[:client_options].ssl = {
|
|
18
|
+
verify: ENV['BOOKINGSYNC_VERIFY_SSL'] != 'false'
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
initializer "bookingsync.controller_helper" do |app|
|
|
25
|
+
require "bookingsync/engine/helpers"
|
|
26
|
+
require "bookingsync/engine/session_helpers"
|
|
27
|
+
require "bookingsync/engine/auth_helpers"
|
|
28
|
+
require "bookingsync/engine/token_helpers"
|
|
29
|
+
|
|
30
|
+
ActiveSupport.on_load :action_controller do
|
|
31
|
+
include BookingSync::Engine::Helpers
|
|
32
|
+
include BookingSync::Engine::SessionHelpers
|
|
33
|
+
include BookingSync::Engine::AuthHelpers
|
|
34
|
+
include BookingSync::Engine::TokenHelpers
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# @return [Boolean]
|
|
39
|
+
cattr_accessor :embedded
|
|
40
|
+
self.embedded = true
|
|
41
|
+
|
|
42
|
+
# Duration of inactivity after which the authorization will be reset.
|
|
43
|
+
# See {BookingSync::Engine::SessionHelpers#sign_out_if_inactive}.
|
|
44
|
+
# @return [Fixnum]
|
|
45
|
+
cattr_accessor :sign_out_after
|
|
46
|
+
self.sign_out_after = 10.minutes
|
|
47
|
+
|
|
48
|
+
# Set the engine into embedded mode.
|
|
49
|
+
#
|
|
50
|
+
# Embedded apps are loaded from within the BookingSync app store, and
|
|
51
|
+
# have a different method to redirect during the OAuth authorization
|
|
52
|
+
# process. <b>This method will not work when the app is not embedded</b>.
|
|
53
|
+
def self.embedded!
|
|
54
|
+
self.embedded = true
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Set the engine into standalone mode.
|
|
58
|
+
#
|
|
59
|
+
# This setting is requried for the applications using this Engine
|
|
60
|
+
# to work outside of the BookingSync app store.
|
|
61
|
+
#
|
|
62
|
+
# Restores the normal mode of redirecting during OAuth authorization.
|
|
63
|
+
def self.standalone!
|
|
64
|
+
self.embedded = false
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# OAuth client configured for the application.
|
|
68
|
+
#
|
|
69
|
+
# The ENV variables used for configuration are described in {file:README.md}.
|
|
70
|
+
#
|
|
71
|
+
# @return [OAuth2::Client] configured OAuth client
|
|
72
|
+
def self.oauth_client
|
|
73
|
+
client_options = {
|
|
74
|
+
site: ENV['BOOKINGSYNC_URL'] || 'https://www.bookingsync.com',
|
|
75
|
+
connection_opts: { headers: { accept: "application/vnd.api+json" } }
|
|
76
|
+
}
|
|
77
|
+
client_options[:ssl] = { verify: ENV['BOOKINGSYNC_VERIFY_SSL'] != 'false' }
|
|
78
|
+
OAuth2::Client.new(ENV['BOOKINGSYNC_APP_ID'], ENV['BOOKINGSYNC_APP_SECRET'],
|
|
79
|
+
client_options)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def self.application_token
|
|
83
|
+
oauth_client.client_credentials.get_token
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
require "bookingsync/engine/model"
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
module BookingSync::Engine::AuthHelpers
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
included do
|
|
5
|
+
rescue_from OAuth2::Error, with: :handle_oauth_error
|
|
6
|
+
rescue_from BookingSync::API::Unauthorized, with: :reset_authorization!
|
|
7
|
+
helper_method :current_account
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
# @return [Account, nil] currently authorized Account or nil if unauthorized
|
|
13
|
+
def current_account
|
|
14
|
+
@current_account ||= ::Account.find_by(uid: session[:account_id]) if session[:account_id].present?
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Callback after account is authorized.
|
|
18
|
+
#
|
|
19
|
+
# Stores the authorized account's uid in the session.
|
|
20
|
+
#
|
|
21
|
+
# @param account [Account] the just authorized account
|
|
22
|
+
def account_authorized(account)
|
|
23
|
+
session[:account_id] = account.uid.to_s
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Clear authorization if the account passed from the BookingSync app store
|
|
27
|
+
# embed doesn't match the currently authorized account
|
|
28
|
+
def enforce_requested_account_authorized!
|
|
29
|
+
clear_authorization! unless requested_account_authorized?
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Checks if the account requested from the BookingSync app store embed
|
|
33
|
+
# matches currently authorized account.
|
|
34
|
+
def requested_account_authorized?
|
|
35
|
+
session[:_bookingsync_account_id].blank? ||
|
|
36
|
+
session[:_bookingsync_account_id] == session[:account_id]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Removes the authorization from session. Will not redirect to any other
|
|
40
|
+
# page, see {#reset_authorization!}
|
|
41
|
+
def clear_authorization!
|
|
42
|
+
session[:account_id] = nil
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Removes authorization from session and requests new authorization.
|
|
46
|
+
# For removing authorization without redirecting, see {#clear_authorization!}.
|
|
47
|
+
def reset_authorization!
|
|
48
|
+
session[:_bookingsync_account_id] =
|
|
49
|
+
params[:account_id].presence || session[:account_id]
|
|
50
|
+
clear_authorization!
|
|
51
|
+
request_authorization!
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def request_authorization!
|
|
55
|
+
if BookingSync::Engine.embedded
|
|
56
|
+
allow_bookingsync_iframe
|
|
57
|
+
path = "/auth/bookingsync/?account_id=#{session[:_bookingsync_account_id]}"
|
|
58
|
+
render text: "<script type='text/javascript'>top.location.href = '#{path}';</script>"
|
|
59
|
+
else
|
|
60
|
+
redirect_to "/auth/bookingsync"
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Handler to rescue OAuth errors
|
|
65
|
+
#
|
|
66
|
+
# @param error [OAuth2::Error] the rescued error
|
|
67
|
+
def handle_oauth_error(error)
|
|
68
|
+
if error.code == "Not authorized"
|
|
69
|
+
current_account.try(:clear_token!)
|
|
70
|
+
reset_authorization!
|
|
71
|
+
else
|
|
72
|
+
raise
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Path to which the user should be redirected after successful authorization.
|
|
77
|
+
# This method should be overridden in applications using this engine.
|
|
78
|
+
#
|
|
79
|
+
# Defaults to root_path.
|
|
80
|
+
def after_bookingsync_sign_in_path
|
|
81
|
+
root_path
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Path to which the user should be redirected after sign out.
|
|
85
|
+
# This method should be overridden in applications using this engine.
|
|
86
|
+
#
|
|
87
|
+
# Defaults to root_path.
|
|
88
|
+
def after_bookingsync_sign_out_path
|
|
89
|
+
root_path
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Requests authorization if not currently authorized.
|
|
93
|
+
def authenticate_account!
|
|
94
|
+
store_bookingsync_account_id if BookingSync::Engine.embedded
|
|
95
|
+
sign_out_if_inactive
|
|
96
|
+
enforce_requested_account_authorized!
|
|
97
|
+
request_authorization! unless current_account
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def store_bookingsync_account_id # :nodoc:
|
|
101
|
+
session[:_bookingsync_account_id] = params.delete(:_bookingsync_account_id)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# General helpers related to integrating applications with BookingSync
|
|
2
|
+
module BookingSync::Engine::Helpers
|
|
3
|
+
extend ActiveSupport::Concern
|
|
4
|
+
|
|
5
|
+
private
|
|
6
|
+
|
|
7
|
+
# Clears the X-Frame-Options header so that the application can be embedded
|
|
8
|
+
# in an iframe. This is required for loading applications in the
|
|
9
|
+
# BookingSync app store.
|
|
10
|
+
#
|
|
11
|
+
# This should set ALLOW-FROM, but it's not supported in Chrome and Safari.
|
|
12
|
+
def allow_bookingsync_iframe
|
|
13
|
+
response.headers['X-Frame-Options'] = '' if ::BookingSync::Engine.embedded
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module BookingSync::Engine::Model
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
module ClassMethods
|
|
5
|
+
def from_omniauth(auth)
|
|
6
|
+
where(auth.slice(:provider, :uid)).first_or_initialize.tap do |account|
|
|
7
|
+
account.provider = auth.provider
|
|
8
|
+
account.uid = auth.uid
|
|
9
|
+
account.name = auth.info.business_name
|
|
10
|
+
|
|
11
|
+
account.update_token(auth.credentials)
|
|
12
|
+
|
|
13
|
+
account.save!
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def token
|
|
19
|
+
@token ||= begin
|
|
20
|
+
token_options = {}
|
|
21
|
+
if oauth_refresh_token
|
|
22
|
+
token_options[:refresh_token] = oauth_refresh_token
|
|
23
|
+
token_options[:expires_at] = oauth_expires_at
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
token = OAuth2::AccessToken.new(BookingSync::Engine.oauth_client,
|
|
27
|
+
oauth_access_token, token_options)
|
|
28
|
+
|
|
29
|
+
if token.expired?
|
|
30
|
+
token = token.refresh!
|
|
31
|
+
update_token!(token)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
token
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def api
|
|
39
|
+
@api ||= BookingSync::API::Client.new(token.token)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def update_token(token)
|
|
43
|
+
self.oauth_access_token = token.token
|
|
44
|
+
self.oauth_refresh_token = token.refresh_token
|
|
45
|
+
self.oauth_expires_at = token.expires_at
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def update_token!(token)
|
|
49
|
+
update_token(token)
|
|
50
|
+
save!
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def clear_token!
|
|
54
|
+
self.oauth_access_token = nil
|
|
55
|
+
self.oauth_refresh_token = nil
|
|
56
|
+
self.oauth_expires_at = nil
|
|
57
|
+
save!
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module BookingSync::Engine::SessionHelpers
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
private
|
|
5
|
+
|
|
6
|
+
# Automatically resets authorization when the session goes inactive.
|
|
7
|
+
# This is only enabled when the engine is set to embedded mode.
|
|
8
|
+
def sign_out_if_inactive
|
|
9
|
+
return unless BookingSync::Engine.embedded
|
|
10
|
+
|
|
11
|
+
last_visit = session[:_bookingsync_last_visit]
|
|
12
|
+
session[:_bookingsync_last_visit] = Time.now.to_i
|
|
13
|
+
|
|
14
|
+
if last_visit && (Time.now.to_i - last_visit > BookingSync::Engine.sign_out_after)
|
|
15
|
+
clear_authorization!
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module BookingSync::Engine::TokenHelpers
|
|
2
|
+
extend ActiveSupport::Concern
|
|
3
|
+
|
|
4
|
+
private
|
|
5
|
+
|
|
6
|
+
# OAuth access token for the current account. Will refresh the token
|
|
7
|
+
# if it's expired and store the new token in the database.
|
|
8
|
+
#
|
|
9
|
+
# @return [OAuth2::AccessToken] access token for current account
|
|
10
|
+
def current_account_token
|
|
11
|
+
current_account.token
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# OAuth access token for the application. The token is obtained from
|
|
15
|
+
# {BookingSync::Engine#appliation_token}.
|
|
16
|
+
#
|
|
17
|
+
# Will fetch new token if the current one is expired.
|
|
18
|
+
#
|
|
19
|
+
# The token is stored in thread local storage, to reduce the amount of
|
|
20
|
+
# token requests.
|
|
21
|
+
#
|
|
22
|
+
# @return [OAuth2::AccessToken] access token for application
|
|
23
|
+
def application_token
|
|
24
|
+
token = Thread.current[:_bookingsync_application_token]
|
|
25
|
+
if token.nil? || token.expired?
|
|
26
|
+
token = Thread.current[:_bookingsync_application_token] =
|
|
27
|
+
BookingSync::Engine.application_token
|
|
28
|
+
end
|
|
29
|
+
token
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'rails/generators'
|
|
2
|
+
require 'rails/generators/migration'
|
|
3
|
+
|
|
4
|
+
module BookingSync
|
|
5
|
+
module Generators
|
|
6
|
+
class InstallGenerator < ::Rails::Generators::Base
|
|
7
|
+
include Rails::Generators::Migration
|
|
8
|
+
|
|
9
|
+
source_root File.join(File.dirname(__FILE__), 'templates')
|
|
10
|
+
|
|
11
|
+
def copy_migrations
|
|
12
|
+
migration_template "create_accounts.rb", "db/migrate/create_accounts.rb"
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|