whiplash-app 0.9.5 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +12 -4
- data/lib/whiplash/app/canonical_host.rb +3 -2
- data/lib/whiplash/app/controller_helpers.rb +131 -8
- data/lib/whiplash/app/railtie.rb +1 -1
- data/lib/whiplash/app/version.rb +1 -1
- data/lib/whiplash/app.rb +14 -1
- data/whiplash-app.gemspec +2 -1
- metadata +19 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c1bf73813a5c4e7bdc0417901e1734afb3dade5b3fbd9e1dc3c8b31b0b0bdcc3
|
4
|
+
data.tar.gz: 7ec1abc0b3adaf3f68d1f43f2c19f42bf700277b0c368e383c42cddedc80e1a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f7b75b10c21856dd22bf2c1d2652ac875f5283d483f56d5123f9b86f93d71bfe76081b3a96cfb4bd5108fddad6f35ce89585128295fafc671ed62913060790c5
|
7
|
+
data.tar.gz: 7950a5979e5e3fbee7f91785507a22dbc5d506c83bcea2acb10ac22708abe13ba55b2fee353c298187df66457fb020bcab812896b81529006f61f8fda24e720a
|
data/README.md
CHANGED
@@ -59,18 +59,26 @@ As long as all of your apps are on the same subdomain, they will share auth cook
|
|
59
59
|
|
60
60
|
```json
|
61
61
|
{
|
62
|
-
"oauth_token": XXXXXXX,
|
63
|
-
"user": {"id":151,"email":"mark@getwhiplash.com","role":"admin","locale":"en","first_name":"Mark","last_name":"Dickson","partner_id":null,
|
62
|
+
"oauth_token": "XXXXXXX",
|
63
|
+
"user": {"id":151,"email":"mark@getwhiplash.com","role":"admin","locale":"en","first_name":"Mark","last_name":"Dickson","partner_id":null, "customer_ids":[1, 2, 3]},
|
64
|
+
"customer": {"id": 123, "name": "BooYaa"},
|
65
|
+
"warehouse": {"id": 1, "name": "Ann Arbor"}
|
64
66
|
}
|
65
67
|
```
|
66
68
|
|
67
69
|
You get a variety of helper methods for free:
|
68
70
|
|
69
71
|
`init_whiplash_api` - This instantiates `@whiplash_api` which can be used to make requests, out of the box
|
70
|
-
`current_user` - This is a **hash** with the above fields; you typically shouldn't need much more user info than this
|
72
|
+
`current_user` - This is a **hash** with the above fields; you typically shouldn't need much more user info than this'
|
73
|
+
`current_customer` - This is a **hash** with the above fields; you typically shouldn't need much more user info than this
|
74
|
+
`current_warehouse` - This is a **hash** with the above fields; you typically shouldn't need much more user info than this
|
71
75
|
`require_user` - Typically you'd use this in a `before_action`. You almost always want this in `ApplicationController`.
|
72
76
|
`set_locale!` - Sets the locale based on the value in the user hash
|
73
|
-
`set_current_user_cookie!` - Updates the current user cookie with fresh data from the api. You typically won't need this, unless your app updates fields like `
|
77
|
+
`set_current_user_cookie!` - Updates the current user cookie with fresh data from the api. You typically won't need this, unless your app updates fields like `locale`.
|
78
|
+
`set_current_customer_cookie!` - Updates the current customer cookie with fresh data from the api; typically used after you've changed customer
|
79
|
+
`set_current_warehouse_cookie!` - Updates the current customer cookie with fresh data from the api; typically used after you've changed warehouse
|
80
|
+
`unset_current_customer_cookie!` - Deletes the current customer cookie, with appropriate domain settings
|
81
|
+
`unset_current_warehouse_cookie!` - Deletes the current warehouse cookie, with appropriate domain settings
|
74
82
|
`core_url` - Shorthand for `ENV['WHIPLASH_API_URL']`
|
75
83
|
`core_url_for` - Link back to Core like `core_url_for('login')`
|
76
84
|
|
@@ -9,7 +9,8 @@ module Whiplash
|
|
9
9
|
def require_canonical_host!
|
10
10
|
canonical_host = ENV.fetch('CANONICAL_HOST', false).in?([true, 'true', 1, '1'])
|
11
11
|
return unless canonical_host
|
12
|
-
|
12
|
+
return unless Rails.configuration.respond_to?(:application_url)
|
13
|
+
application_host = URI.parse(Rails.configuration.application_url).host
|
13
14
|
return if application_host == request.host
|
14
15
|
return unless request.method_symbol == :get # can't redirect PUT, POST, DELETE
|
15
16
|
|
@@ -17,7 +18,7 @@ module Whiplash
|
|
17
18
|
end
|
18
19
|
|
19
20
|
def redirect_to_canonical_host(query_params, status=301)
|
20
|
-
redirect_to "#{Rails.configuration.
|
21
|
+
redirect_to "#{Rails.configuration.application_url}#{request.path}#{'?' if query_params.to_query.present?}#{query_params.to_query}", status: status
|
21
22
|
end
|
22
23
|
|
23
24
|
end
|
@@ -8,21 +8,78 @@ module Whiplash
|
|
8
8
|
helper_method :cookie_domain,
|
9
9
|
:core_url,
|
10
10
|
:core_url_for,
|
11
|
-
:
|
11
|
+
:current_customer,
|
12
|
+
:current_user,
|
13
|
+
:current_warehouse
|
12
14
|
end
|
13
15
|
|
14
16
|
private
|
15
17
|
|
18
|
+
def application_domain
|
19
|
+
return nil if Rails.configuration.application_url.blank?
|
20
|
+
host = URI.parse(Rails.configuration.application_url).host
|
21
|
+
'.' + host
|
22
|
+
end
|
23
|
+
|
24
|
+
def clear_application_cookies!
|
25
|
+
return if application_domain.blank?
|
26
|
+
cookie_keys_we_care_about.each { |k| cookies.delete(k, domain: application_domain) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def clear_domain_cookies!
|
30
|
+
cookie_keys_we_care_about.each { |k| cookies.delete(k, domain: cookie_domain) }
|
31
|
+
end
|
32
|
+
|
16
33
|
def cookie_domain
|
17
|
-
|
34
|
+
host = URI.parse(core_url).host
|
35
|
+
host.gsub!('www.', '')
|
36
|
+
'.' + host
|
37
|
+
end
|
38
|
+
|
39
|
+
def cookie_keys_we_care_about
|
40
|
+
%i(
|
41
|
+
_session
|
42
|
+
customer
|
43
|
+
customer_id
|
44
|
+
oauth_token
|
45
|
+
partner_id
|
46
|
+
user
|
47
|
+
user_id
|
48
|
+
warehouse
|
49
|
+
warehouse_id
|
50
|
+
)
|
18
51
|
end
|
19
52
|
|
20
53
|
def core_url
|
21
|
-
ENV['WHIPLASH_API_URL']
|
54
|
+
ENV['WHIPLASH_CORE_URL'] || ENV['WHIPLASH_API_URL']
|
22
55
|
end
|
23
56
|
|
24
|
-
def core_url_for(path)
|
25
|
-
[core_url, path].join('/')
|
57
|
+
def core_url_for(path, query_params = {})
|
58
|
+
out = [core_url, path].join('/')
|
59
|
+
out = [out, query_params.to_query].join('?') if query_params.present?
|
60
|
+
return out
|
61
|
+
end
|
62
|
+
|
63
|
+
def current_customer
|
64
|
+
return if cookies[:customer].blank?
|
65
|
+
begin
|
66
|
+
customer_hash = JSON.parse(cookies[:customer])
|
67
|
+
@current_customer ||= customer_hash
|
68
|
+
rescue StandardError => e
|
69
|
+
Rails.logger.warn "Customer could not be initialized: #{e.message}"
|
70
|
+
nil
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def current_customer_full
|
75
|
+
return if cookies[:customer].blank?
|
76
|
+
begin
|
77
|
+
customer_hash = JSON.parse(cookies[:customer])
|
78
|
+
@current_customer ||= @whiplash_api.get!("customers/#{customer_hash['id']}").body
|
79
|
+
rescue StandardError => e
|
80
|
+
Rails.logger.warn "Customer could not be initialized: #{e.message}"
|
81
|
+
nil
|
82
|
+
end
|
26
83
|
end
|
27
84
|
|
28
85
|
def current_user
|
@@ -35,12 +92,37 @@ module Whiplash
|
|
35
92
|
end
|
36
93
|
end
|
37
94
|
|
95
|
+
def current_warehouse
|
96
|
+
return if cookies[:warehouse].blank?
|
97
|
+
begin
|
98
|
+
warehouse_hash = JSON.parse(cookies[:warehouse])
|
99
|
+
@current_warehouse ||= warehouse_hash
|
100
|
+
rescue StandardError => e
|
101
|
+
Rails.logger.warn "Warehouse could not be initialized: #{e.message}"
|
102
|
+
@current_warehouse = nil
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def current_warehouse_full
|
107
|
+
return if cookies[:warehouse].blank?
|
108
|
+
begin
|
109
|
+
warehouse_hash = JSON.parse(cookies[:warehouse])
|
110
|
+
@whiplash_api.get!("warehouses/#{warehouse_hash['id']}").body
|
111
|
+
rescue StandardError => e
|
112
|
+
Rails.logger.warn "Warehouse could not be initialized: #{e.message}"
|
113
|
+
nil
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
38
117
|
def http_scheme
|
39
118
|
URI(core_url).scheme
|
40
119
|
end
|
41
120
|
|
42
121
|
def init_whiplash_api(options = {})
|
43
|
-
|
122
|
+
if cookies[:oauth_token].blank?
|
123
|
+
clear_application_cookies!
|
124
|
+
return redirect_to core_url_for('login', redirect_url: request.original_url)
|
125
|
+
end
|
44
126
|
token = {access_token: cookies[:oauth_token]}
|
45
127
|
begin
|
46
128
|
@whiplash_api = Whiplash::App.new(token, options)
|
@@ -51,7 +133,9 @@ module Whiplash
|
|
51
133
|
end
|
52
134
|
|
53
135
|
def require_user
|
54
|
-
|
136
|
+
return if current_user.present?
|
137
|
+
clear_application_cookies!
|
138
|
+
redirect_to core_url_for('login', redirect_url: request.original_url)
|
55
139
|
end
|
56
140
|
|
57
141
|
def set_locale!
|
@@ -59,10 +143,25 @@ module Whiplash
|
|
59
143
|
I18n.locale = current_user.try('locale') || I18n.default_locale
|
60
144
|
end
|
61
145
|
|
146
|
+
def set_current_customer_cookie!(customer_id, expires_at = nil)
|
147
|
+
customer = @whiplash_api.get!("customers/#{customer_id}").body
|
148
|
+
user = @whiplash_api.get!("me").body
|
149
|
+
fields_we_care_about = %w(id name)
|
150
|
+
customer_hash = customer.slice(*fields_we_care_about)
|
151
|
+
expires_at ||= user['current_sign_in_expires_at']
|
152
|
+
|
153
|
+
shared_values = {
|
154
|
+
expires: DateTime.parse(expires_at),
|
155
|
+
secure: http_scheme == 'https',
|
156
|
+
samesite: :strict,
|
157
|
+
domain: cookie_domain
|
158
|
+
}
|
159
|
+
cookies[:customer] = shared_values.merge(value: customer_hash.to_json)
|
160
|
+
end
|
62
161
|
|
63
162
|
def set_current_user_cookie!(expires_at = nil)
|
64
163
|
user = @whiplash_api.get!("me").body
|
65
|
-
fields_we_care_about = %w(id email role locale first_name last_name partner_id
|
164
|
+
fields_we_care_about = %w(id email role locale first_name last_name partner_id customer_ids)
|
66
165
|
user_hash = user.slice(*fields_we_care_about)
|
67
166
|
expires_at ||= user['current_sign_in_expires_at']
|
68
167
|
|
@@ -75,6 +174,30 @@ module Whiplash
|
|
75
174
|
cookies[:user] = shared_values.merge(value: user_hash.to_json)
|
76
175
|
end
|
77
176
|
|
177
|
+
def set_current_warehouse_cookie!(warehouse_id, expires_at = nil)
|
178
|
+
warehouse = @whiplash_api.get!("warehouses/#{warehouse_id}").body
|
179
|
+
user = @whiplash_api.get!("me").body
|
180
|
+
fields_we_care_about = %w(id name slug)
|
181
|
+
warehouse_hash = warehouse.slice(*fields_we_care_about)
|
182
|
+
expires_at ||= user['current_sign_in_expires_at']
|
183
|
+
|
184
|
+
shared_values = {
|
185
|
+
expires: DateTime.parse(expires_at),
|
186
|
+
secure: http_scheme == 'https',
|
187
|
+
samesite: :strict,
|
188
|
+
domain: cookie_domain
|
189
|
+
}
|
190
|
+
cookies[:warehouse] = shared_values.merge(value: warehouse_hash.to_json)
|
191
|
+
end
|
192
|
+
|
193
|
+
def unset_current_customer_cookie!
|
194
|
+
cookies.delete(:customer, domain: cookie_domain)
|
195
|
+
end
|
196
|
+
|
197
|
+
def unset_current_warehouse_cookie!
|
198
|
+
cookies.delete(:warehouse, domain: cookie_domain)
|
199
|
+
end
|
200
|
+
|
78
201
|
end
|
79
202
|
end
|
80
203
|
end
|
data/lib/whiplash/app/railtie.rb
CHANGED
@@ -20,7 +20,7 @@ module Whiplash
|
|
20
20
|
end
|
21
21
|
|
22
22
|
initializer "whiplash_app.action_controller" do
|
23
|
-
ActiveSupport.on_load(:
|
23
|
+
ActiveSupport.on_load(:action_controller_base) do
|
24
24
|
include Whiplash::App::CanonicalHost
|
25
25
|
include Whiplash::App::ControllerHelpers
|
26
26
|
end
|
data/lib/whiplash/app/version.rb
CHANGED
data/lib/whiplash/app.rb
CHANGED
@@ -6,6 +6,7 @@ require "whiplash/app/version"
|
|
6
6
|
require "errors/whiplash_api_error"
|
7
7
|
require "oauth2"
|
8
8
|
require "faraday"
|
9
|
+
require 'faraday/net_http_persistent'
|
9
10
|
|
10
11
|
# Rails app stuff
|
11
12
|
if defined?(Rails::Railtie)
|
@@ -40,9 +41,21 @@ module Whiplash
|
|
40
41
|
|
41
42
|
def connection
|
42
43
|
Faraday.new [self.class.api_url, versioned_api_url].join("/") do |conn|
|
44
|
+
# Authentication
|
43
45
|
conn.request :authorization, 'Bearer', token.token
|
44
46
|
conn.request :json
|
45
47
|
conn.response :json, :content_type => /\bjson$/
|
48
|
+
conn.options.timeout = 30 # Total request timeout
|
49
|
+
conn.options.open_timeout = 5 # Connection establishment timeout
|
50
|
+
|
51
|
+
# Use persistent HTTP connections (requires net-http-persistent gem)
|
52
|
+
begin
|
53
|
+
conn.adapter :net_http_persistent
|
54
|
+
rescue LoadError
|
55
|
+
# Fallback to default adapter if net-http-persistent isn't available
|
56
|
+
Rails.logger.warn "[WhiplashApp] net-http-persistent gem not found, using default adapter" if defined?(Rails)
|
57
|
+
conn.adapter Faraday.default_adapter
|
58
|
+
end
|
46
59
|
end
|
47
60
|
end
|
48
61
|
|
@@ -112,4 +125,4 @@ module Net
|
|
112
125
|
|
113
126
|
end
|
114
127
|
end
|
115
|
-
end
|
128
|
+
end
|
data/whiplash-app.gemspec
CHANGED
@@ -20,9 +20,10 @@ Gem::Specification.new do |spec|
|
|
20
20
|
|
21
21
|
spec.add_dependency "oauth2", "~> 2.0.4"
|
22
22
|
spec.add_dependency "faraday", "~> 2.7"
|
23
|
+
spec.add_dependency 'faraday-net_http_persistent'
|
23
24
|
|
24
25
|
spec.add_development_dependency "bundler", ">= 2.2"
|
25
26
|
spec.add_development_dependency "rake", ">= 12.3.3"
|
26
27
|
spec.add_development_dependency "rspec", "~> 3.0"
|
27
|
-
spec.add_development_dependency "pry"
|
28
|
+
spec.add_development_dependency "pry", "~> 0.14"
|
28
29
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: whiplash-app
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Don Sullivan, Mark Dickson
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-05-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: oauth2
|
@@ -38,6 +38,20 @@ dependencies:
|
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '2.7'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: faraday-net_http_persistent
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
41
55
|
- !ruby/object:Gem::Dependency
|
42
56
|
name: bundler
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,14 +100,14 @@ dependencies:
|
|
86
100
|
requirements:
|
87
101
|
- - "~>"
|
88
102
|
- !ruby/object:Gem::Version
|
89
|
-
version: 0.
|
103
|
+
version: '0.14'
|
90
104
|
type: :development
|
91
105
|
prerelease: false
|
92
106
|
version_requirements: !ruby/object:Gem::Requirement
|
93
107
|
requirements:
|
94
108
|
- - "~>"
|
95
109
|
- !ruby/object:Gem::Version
|
96
|
-
version: 0.
|
110
|
+
version: '0.14'
|
97
111
|
description: this gem provides connectivity to the Whiplash API for authentication
|
98
112
|
and REST requests.
|
99
113
|
email:
|
@@ -141,7 +155,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
141
155
|
- !ruby/object:Gem::Version
|
142
156
|
version: '0'
|
143
157
|
requirements: []
|
144
|
-
rubygems_version: 3.
|
158
|
+
rubygems_version: 3.1.6
|
145
159
|
signing_key:
|
146
160
|
specification_version: 4
|
147
161
|
summary: this gem provides connectivity to the Whiplash API for authentication and
|