hubrise_app 0.1.2 → 1.1.1
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/LICENSE +21 -0
- data/README.md +78 -2
- data/app/controllers/hubrise_app/application_controller/app_instance_methods.rb +28 -0
- data/app/controllers/hubrise_app/application_controller/hubrise_gateway_methods.rb +25 -0
- data/app/controllers/hubrise_app/application_controller/session_methods.rb +33 -0
- data/app/controllers/hubrise_app/application_controller.rb +3 -66
- data/app/controllers/hubrise_app/callback_controller/action_disconnect.rb +5 -0
- data/app/controllers/hubrise_app/callback_controller/action_event.rb +5 -0
- data/app/controllers/hubrise_app/callback_controller.rb +19 -14
- data/app/controllers/hubrise_app/oauth_controller/action_authorize_callback.rb +13 -0
- data/app/controllers/hubrise_app/oauth_controller/action_connect_callback.rb +12 -0
- data/app/controllers/hubrise_app/oauth_controller/action_login_callback.rb +7 -0
- data/app/controllers/hubrise_app/oauth_controller.rb +8 -33
- data/app/controllers/hubrise_app/sessions_controller.rb +9 -0
- data/app/lib/hubrise_app/config_loader.rb +5 -0
- data/app/lib/hubrise_app/hubrise_gateway.rb +48 -24
- data/app/lib/hubrise_app/refresher/account.rb +15 -0
- data/app/lib/hubrise_app/refresher/app_instance.rb +24 -0
- data/app/lib/hubrise_app/refresher/base.rb +45 -0
- data/app/lib/hubrise_app/refresher/catalog.rb +13 -0
- data/app/lib/hubrise_app/refresher/customer_list.rb +13 -0
- data/app/lib/hubrise_app/refresher/location.rb +13 -0
- data/app/lib/hubrise_app/refresher/user.rb +16 -0
- data/app/lib/hubrise_app/services/assign_app_instance.rb +8 -0
- data/app/lib/hubrise_app/services/connect_app_instance.rb +3 -4
- data/app/lib/hubrise_app/services/resolve_app_instance.rb +5 -0
- data/app/models/account.rb +2 -0
- data/app/models/app_instance.rb +2 -0
- data/app/models/catalog.rb +2 -0
- data/app/models/customer_list.rb +2 -0
- data/app/models/hubrise_app/account_base.rb +7 -0
- data/app/models/hubrise_app/app_instance_base.rb +10 -0
- data/app/models/hubrise_app/catalog_base.rb +7 -0
- data/app/models/hubrise_app/customer_list_base.rb +7 -0
- data/app/models/hubrise_app/location_base.rb +11 -0
- data/app/models/hubrise_app/user_app_instance_base.rb +12 -0
- data/app/models/hubrise_app/user_base.rb +18 -0
- data/app/models/location.rb +2 -0
- data/app/models/user.rb +2 -0
- data/app/models/user_app_instance.rb +2 -0
- data/config/initializers/hubrise_app_config.rb +1 -1
- data/config/routes.rb +2 -0
- data/db/migrate/20190116155419_create_base_tables.rb +27 -23
- data/db/migrate/20200829091933_add_locations_timezone.rb +5 -0
- data/db/migrate/20210120142001_add_api_json_column.rb +6 -0
- data/db/migrate/20210121150253_remove_replaced_by_api_data_columns.rb +9 -0
- data/db/migrate/20210419120038_add_catalogs_and_customer_lists.rb +28 -0
- data/lib/hubrise_app/spec_support.rb +3 -0
- data/lib/hubrise_app/version.rb +1 -1
- metadata +46 -21
- data/MIT-LICENSE +0 -20
- data/app/lib/hubrise_app/services/disconnect_app_instance.rb +0 -6
- data/app/lib/hubrise_app/services/handle_event.rb +0 -22
- data/app/lib/hubrise_app/services/override/connect_app_instance.rb +0 -1
- data/app/lib/hubrise_app/services/override/disconnect_app_instance.rb +0 -1
- data/app/lib/hubrise_app/services/override/handle_event.rb +0 -1
- data/app/models/concerns/hubrise_app/hr_api_resource.rb +0 -29
- data/app/models/hubrise_app/hr_account.rb +0 -19
- data/app/models/hubrise_app/hr_app_instance.rb +0 -35
- data/app/models/hubrise_app/hr_location.rb +0 -11
- data/app/models/hubrise_app/hr_user.rb +0 -35
- data/app/models/hubrise_app/hr_user_app_instance.rb +0 -14
- data/app/models/hubrise_app/override/hr_user.rb +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 752df0a174985157db351f3086761ff039dbeed5f8fc99e11aa9427438d1fdae
|
4
|
+
data.tar.gz: 4e563cb2b305f54bc88cfe3e197c7b00eb537060b01aa1b703a0261ca8736835
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 34248f447c609c2965bf013ead89c9399325d71578767aa21d1e5f9ccb4ceac2789dfa504f9dc25e030db89b11c537a9f0beb5abc2ef7bcaa3c8d535fd76db65
|
7
|
+
data.tar.gz: b28e0a2d75bf14d46f300bbc2b78b5429c7a9c4baee544e69b78d9ec34a609b089e5c28a67113790f9c56e8c01cfed58c2d0f131ad267ef0071f306e22819e04
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2016- HubRise (https://www.hubrise.com)
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,5 +1,81 @@
|
|
1
|
-
|
2
|
-
|
1
|
+

|
2
|
+
|
3
|
+
|
4
|
+
## Installation
|
5
|
+
|
6
|
+
Refer to https://github.com/HubRise/ruby-app/tree/master/spec/dummy/ for examples
|
7
|
+
|
8
|
+
1. Install the gem (`gem "hubrise_app", git: "https://github.com/HubRise/ruby-app.git"` for now)
|
9
|
+
2. Add `hubrise_app/config.yaml`
|
10
|
+
3. Copy migrations with `rake hubrise_app:install:migrations` and migrate
|
11
|
+
4. Mount engine routes with `mount HubriseApp::Engine => "/"`
|
12
|
+
5. Define `hubrise_open_path` rails route (e.g. `get :hubrise_open, to: "application#open"`)
|
13
|
+
6. Inherit your `ApplicationController` and apply fundamental `before_actions`:
|
14
|
+
```
|
15
|
+
class ApplicationController < HubriseApp::ApplicationController
|
16
|
+
before_action :ensure_authenticated!
|
17
|
+
before_action :ensure_app_instance_found!
|
18
|
+
|
19
|
+
def open
|
20
|
+
render plain: current_user.full_name + " | " + current_app_instance.hr_id
|
21
|
+
end
|
22
|
+
end
|
23
|
+
```
|
24
|
+
|
25
|
+
## Intro
|
26
|
+
|
27
|
+
This gem provides a framework for a Hubrise App with a Resource Based Access.
|
28
|
+
This means that each Hubrise User will be able to create a connection (App Instance) to multiple Accounts and Locations. And this connection will be shared with any other Hubrise User that has access to the same reseources on Hubrise side automatically.
|
29
|
+
|
30
|
+
### Note
|
31
|
+
The main app's scopes (`account_scope` and `location_scope`) must not include any kind of `profile` access. Otherwise it will make no sense to share the connection with other users.
|
32
|
+
|
33
|
+
## Documentation
|
34
|
+
|
35
|
+
The framework is based on 3 different Oauth Workflows: `Connect Workflow`, `Login Workflow` and `Authorize Workflow`.
|
36
|
+
And 4 main entities: `User`, `AppInstance`, `Account`, `Location`.
|
37
|
+
|
38
|
+
### Connect Workflow
|
39
|
+
Usualy this workflow gets triggered by clicking the "Install" button from the Hubrise App Market.
|
40
|
+
It requests the main connection with the `location_scope` or `account_scope` (which are specified by developer during app creation).
|
41
|
+
|
42
|
+
Once it has been completed a new `AppInstance` gets persisted in the DB.
|
43
|
+
`Account` and `Location` instances are being created automaticaly depending on the scope and populated from the api.
|
44
|
+
Note: this workflow is not responsible for creating a `User` record, it **only** happens in `Login Workflow`.
|
45
|
+
|
46
|
+
- If there's a user already logged in - the new app instance gets associated with this user automatically. And the user gets redirected to `hubrise_open_path` with a `app_instance_id` params.
|
47
|
+
|
48
|
+
- If there's no user logged in - the `Login Workflow` is triggered right away by redirecting to login oauth url.
|
49
|
+
|
50
|
+
|
51
|
+
Code: https://github.com/HubRise/ruby-app/tree/master/app/controllers/hubrise_app/oauth_controller/action_connect_callback.rb
|
52
|
+
|
53
|
+
### Login Workflow
|
54
|
+
Usualy this workflow gets triggered after `Connect Workflow` or by the `ensure_authenticated!` filter for any anon access.
|
55
|
+
It requests `profile_with_email` scope.
|
56
|
+
Once completed - a new `User` gets persisted in the DB with a profile `access_token` and redirected to `hubrise_open_path`.
|
57
|
+
|
58
|
+
|
59
|
+
### Authorize Workflow
|
60
|
+
This workflow gets triggered by `ensure_app_instance_found!` whenever a logged in user does not have access (or it is expired) to `AppInstance` specified by `app_instance_id` param.
|
61
|
+
If `app_instance_id` is not specified - its considered to be a broken request and a fatal error message is shown.
|
62
|
+
|
63
|
+
Note: when a user opens already installed app by clicking the button from Hubrise Manager - it opens the `open_url` (specified by developer during app creation) with a `app_instance_id` param.
|
64
|
+
|
65
|
+
This `app_instance_id` param is carried on from request to request using `default_url_options`: https://github.com/HubRise/ruby-app/tree/master/app/controllers/hubrise_app/application_controller/app_instance_methods.rb#L26
|
66
|
+
|
67
|
+
|
68
|
+
A use case:
|
69
|
+
1. UserA installs an app for Account1 - an `AppInstance` with `hr_id=abcd` being created
|
70
|
+
2. UserA adds UserB as a manager to Account1 (via Hubrise Manager user roles table)
|
71
|
+
3. UserB opens the installed app by clicking the button in the dashboard. It redirects to `open_url` with `app_instance_id=abcd`
|
72
|
+
4. UserB hits the `ensure_authenticated!` wall and agrees - a `User` record being created
|
73
|
+
5. UserB hits the `ensure_app_instance_found!` wall and agrees - a `UserAppInstace` being created for the user and `AppInstance` with `hr_id=abcd`
|
74
|
+
6. UserB now has access to the `AppInstance`
|
75
|
+
|
76
|
+
|
77
|
+
## Extension
|
78
|
+
TODO
|
3
79
|
|
4
80
|
## License
|
5
81
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module HubriseApp::ApplicationController::AppInstanceMethods
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
included do
|
4
|
+
helper_method :current_app_instance
|
5
|
+
end
|
6
|
+
|
7
|
+
def hr_app_instance_id
|
8
|
+
params[:app_instance_id]
|
9
|
+
end
|
10
|
+
|
11
|
+
def current_app_instance
|
12
|
+
if current_user
|
13
|
+
@app_instance ||= HubriseApp::Services::ResolveAppInstance.run(current_user.app_instances, hr_app_instance_id, self)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def ensure_app_instance_found!
|
18
|
+
if hr_app_instance_id.blank?
|
19
|
+
render(plain: "Something went wrong. Please try to reopen from Hubrise Dashboard.")
|
20
|
+
elsif current_app_instance.nil?
|
21
|
+
redirect_to(build_hubrise_oauth_authorize_url, allow_other_host: true)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def default_url_options
|
26
|
+
super.merge(app_instance_id: hr_app_instance_id || current_app_instance&.hr_id)
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module HubriseApp::ApplicationController::HubriseGatewayMethods
|
2
|
+
def hubrise_gateway
|
3
|
+
@hubrise_gateway ||= HubriseApp::HubriseGateway.new
|
4
|
+
end
|
5
|
+
|
6
|
+
def build_hubrise_oauth_login_url
|
7
|
+
hubrise_gateway.build_login_authorization_url(build_hubrise_oauth_login_callback_url)
|
8
|
+
end
|
9
|
+
|
10
|
+
def build_hubrise_oauth_authorize_url
|
11
|
+
hubrise_gateway.build_app_authorization_url(hr_app_instance_id, build_hubrise_oauth_authorize_callback_url)
|
12
|
+
end
|
13
|
+
|
14
|
+
def build_hubrise_oauth_login_callback_url
|
15
|
+
hubrise_app.hubrise_oauth_login_callback_url
|
16
|
+
end
|
17
|
+
|
18
|
+
def build_hubrise_oauth_authorize_callback_url
|
19
|
+
hubrise_app.hubrise_oauth_authorize_callback_url
|
20
|
+
end
|
21
|
+
|
22
|
+
def build_hubrise_open_url
|
23
|
+
main_app.hubrise_open_path
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module HubriseApp::ApplicationController::SessionMethods
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
included do
|
4
|
+
protect_from_forgery with: :reset_session
|
5
|
+
helper_method :current_user, :logged_in?
|
6
|
+
end
|
7
|
+
|
8
|
+
def login(user)
|
9
|
+
session[:user_id] = user.id
|
10
|
+
@current_user = user
|
11
|
+
end
|
12
|
+
|
13
|
+
def logout
|
14
|
+
session[:user_id] = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
def current_user
|
18
|
+
@current_user ||= User.where(id: session[:user_id]).take
|
19
|
+
end
|
20
|
+
|
21
|
+
def logged_in?
|
22
|
+
!!current_user
|
23
|
+
end
|
24
|
+
|
25
|
+
def ensure_authenticated!
|
26
|
+
unless logged_in?
|
27
|
+
redirect_to(build_hubrise_oauth_login_url, allow_other_host: true)
|
28
|
+
return
|
29
|
+
end
|
30
|
+
|
31
|
+
yield if block_given?
|
32
|
+
end
|
33
|
+
end
|
@@ -1,70 +1,7 @@
|
|
1
1
|
module HubriseApp
|
2
2
|
class ApplicationController < ActionController::Base
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
protected
|
7
|
-
|
8
|
-
###########
|
9
|
-
# SESSION #
|
10
|
-
###########
|
11
|
-
|
12
|
-
def login(hr_user)
|
13
|
-
session[:user_id] = hr_user.id
|
14
|
-
@current_hr_user = hr_user
|
15
|
-
end
|
16
|
-
|
17
|
-
def logout
|
18
|
-
session[:user_id] = nil
|
19
|
-
end
|
20
|
-
|
21
|
-
def current_hr_user
|
22
|
-
@current_hr_user ||= HrUser.where(id: session[:user_id]).take
|
23
|
-
end
|
24
|
-
|
25
|
-
def logged_in?
|
26
|
-
!!current_hr_user
|
27
|
-
end
|
28
|
-
|
29
|
-
def ensure_authenticated!
|
30
|
-
redirect_to(build_hubrise_oauth_login_url) unless logged_in?
|
31
|
-
end
|
32
|
-
|
33
|
-
##############
|
34
|
-
# HR METHODS #
|
35
|
-
##############
|
36
|
-
|
37
|
-
def hr_app_instance_id
|
38
|
-
params[:app_instance_id]
|
39
|
-
end
|
40
|
-
|
41
|
-
def default_url_options
|
42
|
-
super.merge(app_instance_id: hr_app_instance_id || current_hr_app_instance&.hr_id)
|
43
|
-
end
|
44
|
-
|
45
|
-
def current_hr_app_instance
|
46
|
-
@hr_app_instance ||= current_hr_user && begin
|
47
|
-
current_hr_user.hr_app_instances.where(hr_id: hr_app_instance_id).includes(:hr_account, :hr_location).take
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
def build_hubrise_oauth_login_url
|
52
|
-
HubriseGateway.build_login_authorization_url(
|
53
|
-
hubrise_app.hubrise_oauth_login_callback_url
|
54
|
-
)
|
55
|
-
end
|
56
|
-
|
57
|
-
def build_hubrise_oauth_authorize_url
|
58
|
-
HubriseGateway.build_app_authorization_url(hr_app_instance_id,
|
59
|
-
hubrise_app.hubrise_oauth_authorize_callback_url)
|
60
|
-
end
|
61
|
-
|
62
|
-
def ensure_hr_app_instance_found!
|
63
|
-
if hr_app_instance_id.blank?
|
64
|
-
render(plain: "Something went wrong. Please try to reopen from Hubrise Dashboard.")
|
65
|
-
elsif current_hr_app_instance.nil?
|
66
|
-
redirect_to(build_hubrise_oauth_authorize_url)
|
67
|
-
end
|
68
|
-
end
|
3
|
+
include AppInstanceMethods
|
4
|
+
include HubriseGatewayMethods
|
5
|
+
include SessionMethods
|
69
6
|
end
|
70
7
|
end
|
@@ -1,26 +1,31 @@
|
|
1
1
|
module HubriseApp
|
2
|
-
class CallbackController <
|
2
|
+
class CallbackController < ApplicationController
|
3
3
|
skip_before_action :verify_authenticity_token
|
4
|
-
before_action :
|
4
|
+
before_action :ensure_app_instance_found!
|
5
|
+
before_action :verify_event!, only: :event
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
include ActionEvent
|
8
|
+
include ActionDisconnect
|
9
|
+
|
10
|
+
protected
|
10
11
|
|
11
|
-
def
|
12
|
-
Services::
|
13
|
-
head 200
|
12
|
+
def current_app_instance
|
13
|
+
HubriseApp::Services::ResolveAppInstance.run(AppInstance, params[:app_instance_id], self)
|
14
14
|
end
|
15
15
|
|
16
|
-
|
16
|
+
def ensure_app_instance_found!
|
17
|
+
head(404) unless current_app_instance
|
18
|
+
end
|
17
19
|
|
18
|
-
def
|
19
|
-
|
20
|
+
def event_params
|
21
|
+
params.require(:callback).permit!.to_h
|
20
22
|
end
|
21
23
|
|
22
|
-
def
|
23
|
-
|
24
|
+
def verify_event!
|
25
|
+
unless hubrise_gateway.valid_hmac?(request.raw_post,
|
26
|
+
request.headers["X-Hubrise-Hmac-Sha256"])
|
27
|
+
render(plain: "Invalid HubRise HMAC", status: 401)
|
28
|
+
end
|
24
29
|
end
|
25
30
|
end
|
26
31
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module HubriseApp::OauthController::ActionAuthorizeCallback
|
2
|
+
# authorize access to specific app_instance (expirable)
|
3
|
+
def authorize_callback
|
4
|
+
ensure_authenticated! do
|
5
|
+
if current_app_instance
|
6
|
+
HubriseApp::Services::AssignAppInstance.run(current_user, current_app_instance, self)
|
7
|
+
redirect_to(build_hubrise_open_url)
|
8
|
+
else
|
9
|
+
render(plain: "Something went wrong. Please try to reinstall the app")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module HubriseApp::OauthController::ActionConnectCallback
|
2
|
+
def connect_callback
|
3
|
+
@app_instance = HubriseApp::Services::ConnectAppInstance.run(api_client_from_oauth_code, self)
|
4
|
+
|
5
|
+
if logged_in?
|
6
|
+
HubriseApp::Services::AssignAppInstance.run(current_user, @app_instance, self)
|
7
|
+
redirect_to(build_hubrise_open_url)
|
8
|
+
else
|
9
|
+
redirect_to(build_hubrise_oauth_login_url, allow_other_host: true)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -1,44 +1,19 @@
|
|
1
1
|
module HubriseApp
|
2
2
|
class OauthController < ApplicationController
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
hr_user = HrUser.refresh_or_create_via_api_client(api_client_from_oauth_code)
|
7
|
-
login(hr_user)
|
8
|
-
redirect_to(main_app.hubrise_open_path)
|
9
|
-
end
|
10
|
-
|
11
|
-
def connect_callback
|
12
|
-
@hr_app_instance = HrAppInstance.refresh_or_create_via_api_client(api_client_from_oauth_code)
|
13
|
-
|
14
|
-
Services::ConnectAppInstance.run(current_hr_app_instance, hubrise_callback_event_url: hubrise_callback_event_url)
|
15
|
-
|
16
|
-
if logged_in?
|
17
|
-
current_hr_user.assign_hr_app_instance(current_hr_app_instance)
|
18
|
-
redirect_to(main_app.hubrise_open_path)
|
19
|
-
else
|
20
|
-
redirect_to(build_hubrise_oauth_login_url)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
# authorize access to specific app_instance (expirable)
|
25
|
-
def authorize_callback
|
26
|
-
if current_hr_app_instance
|
27
|
-
current_hr_user.assign_hr_app_instance(current_hr_app_instance)
|
28
|
-
redirect_to(main_app.hubrise_open_path)
|
29
|
-
else
|
30
|
-
render(plain: "Something went wrong. Please try to reinstall the app")
|
31
|
-
end
|
32
|
-
end
|
3
|
+
include ActionLoginCallback
|
4
|
+
include ActionConnectCallback
|
5
|
+
include ActionAuthorizeCallback
|
33
6
|
|
34
7
|
protected
|
35
8
|
|
36
|
-
def
|
37
|
-
@
|
9
|
+
def current_app_instance
|
10
|
+
@app_instance ||= HubriseApp::Services::ResolveAppInstance.run(
|
11
|
+
AppInstance, api_client_from_oauth_code.app_instance_id, self
|
12
|
+
)
|
38
13
|
end
|
39
14
|
|
40
15
|
def api_client_from_oauth_code
|
41
|
-
@
|
16
|
+
@api_client ||= hubrise_gateway.build_api_client_from_authorization_code(params[:code])
|
42
17
|
end
|
43
18
|
end
|
44
19
|
end
|
@@ -1,34 +1,58 @@
|
|
1
1
|
class HubriseApp::HubriseGateway
|
2
2
|
HUBRISE_LOGIN_SCOPE = "profile_with_email".freeze
|
3
|
-
HUBRISE_API_VERSION = :v1
|
4
3
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
4
|
+
def initialize(config = HubriseApp::CONFIG)
|
5
|
+
@config = config
|
6
|
+
end
|
7
|
+
|
8
|
+
def build_api_client(params = {})
|
9
|
+
HubriseClient::V1.new(
|
10
|
+
@config[:hubrise_client_id],
|
11
|
+
@config[:hubrise_client_secret],
|
12
|
+
params.merge(
|
13
|
+
oauth_host: @config[:hubrise_oauth_host],
|
14
|
+
oauth_port: @config[:hubrise_oauth_port],
|
15
|
+
api_host: @config[:hubrise_api_host],
|
16
|
+
api_port: @config[:hubrise_api_port],
|
17
|
+
use_https: @config[:hubrise_use_https]
|
17
18
|
)
|
18
|
-
|
19
|
+
)
|
20
|
+
end
|
19
21
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
22
|
+
def build_api_client_from_app_instance(app_instance)
|
23
|
+
build_api_client(
|
24
|
+
access_token: app_instance.access_token,
|
25
|
+
app_instance_id: app_instance.hr_id,
|
26
|
+
account_id: app_instance.hr_account_id,
|
27
|
+
location_id: app_instance.hr_location_id,
|
28
|
+
catalog_id: app_instance.hr_catalog_id,
|
29
|
+
customer_list_id: app_instance.hr_customer_list_id
|
30
|
+
)
|
31
|
+
end
|
25
32
|
|
26
|
-
|
27
|
-
|
33
|
+
def build_api_client_from_authorization_code(authorization_code)
|
34
|
+
build_api_client.tap do |api_client|
|
35
|
+
api_client.authorize!(authorization_code)
|
28
36
|
end
|
37
|
+
end
|
29
38
|
|
30
|
-
|
31
|
-
|
32
|
-
|
39
|
+
def build_login_authorization_url(redirect_uri)
|
40
|
+
build_api_client.build_authorization_url(redirect_uri, HUBRISE_LOGIN_SCOPE)
|
41
|
+
end
|
42
|
+
|
43
|
+
def build_app_authorization_url(hr_app_instance_id, redirect_uri)
|
44
|
+
build_api_client.build_authorization_url(redirect_uri, nil, app_instance_id: hr_app_instance_id)
|
45
|
+
end
|
46
|
+
|
47
|
+
def valid_hmac?(body, request_hmac)
|
48
|
+
calculated_hmac = OpenSSL::HMAC.hexdigest(
|
49
|
+
OpenSSL::Digest.new("sha256"),
|
50
|
+
@config[:hubrise_client_secret],
|
51
|
+
body
|
52
|
+
)
|
53
|
+
ActiveSupport::SecurityUtils.secure_compare(
|
54
|
+
calculated_hmac,
|
55
|
+
request_hmac || ""
|
56
|
+
)
|
33
57
|
end
|
34
58
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module HubriseApp::Refresher
|
2
|
+
class Account < Base
|
3
|
+
class << self
|
4
|
+
def fetch_attributes(resource, api_client)
|
5
|
+
{
|
6
|
+
api_data: if api_client.location_id
|
7
|
+
api_client.get_location(api_client.location_id).data["account"]
|
8
|
+
else
|
9
|
+
api_client.get_account(resource.hr_id).data
|
10
|
+
end.except("id")
|
11
|
+
}
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module HubriseApp::Refresher
|
2
|
+
class AppInstance < Base
|
3
|
+
class << self
|
4
|
+
def run(resource, api_client, *refresher_args)
|
5
|
+
resource.update!(
|
6
|
+
access_token: api_client.access_token,
|
7
|
+
account: HubriseApp::Refresher::Account.from_api_client(
|
8
|
+
api_client, *refresher_args
|
9
|
+
),
|
10
|
+
location: HubriseApp::Refresher::Location.from_api_client(
|
11
|
+
api_client, *refresher_args
|
12
|
+
),
|
13
|
+
catalog: HubriseApp::Refresher::Catalog.from_api_client(
|
14
|
+
api_client, *refresher_args
|
15
|
+
),
|
16
|
+
customer_list: HubriseApp::Refresher::CustomerList.from_api_client(
|
17
|
+
api_client, *refresher_args
|
18
|
+
)
|
19
|
+
)
|
20
|
+
resource
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class HubriseApp::Refresher::Base
|
2
|
+
REFRESH_THRESHOLD = 1.day
|
3
|
+
|
4
|
+
class << self
|
5
|
+
def from_api_client(api_client, *args)
|
6
|
+
hr_id = api_client.public_send(id_key)
|
7
|
+
if hr_id
|
8
|
+
run(
|
9
|
+
model_factory.find_or_initialize_by(hr_id: hr_id),
|
10
|
+
api_client,
|
11
|
+
*args
|
12
|
+
)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def run(resource, api_client, force: false)
|
17
|
+
return resource if !stale?(resource) && !force
|
18
|
+
|
19
|
+
resource.update!(
|
20
|
+
fetch_attributes(resource, api_client).merge(
|
21
|
+
refreshed_at: Time.now,
|
22
|
+
)
|
23
|
+
)
|
24
|
+
resource
|
25
|
+
end
|
26
|
+
|
27
|
+
protected
|
28
|
+
|
29
|
+
def fetch_attributes(_resource, _api_client)
|
30
|
+
{}
|
31
|
+
end
|
32
|
+
|
33
|
+
def stale?(resource)
|
34
|
+
resource.refreshed_at.nil? || Time.now - resource.refreshed_at > REFRESH_THRESHOLD
|
35
|
+
end
|
36
|
+
|
37
|
+
def model_factory
|
38
|
+
const_get("::" + self.name.demodulize)
|
39
|
+
end
|
40
|
+
|
41
|
+
def id_key
|
42
|
+
self.name.demodulize.underscore + "_id"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|