hubrise_app 1.0.0 → 1.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 +4 -4
- data/README.md +76 -2
- data/app/controllers/hubrise_app/application_controller/app_instance_methods.rb +8 -8
- data/app/controllers/hubrise_app/application_controller/session_methods.rb +8 -8
- data/app/controllers/hubrise_app/callback_controller.rb +14 -6
- data/app/controllers/hubrise_app/oauth_controller/action_authorize_callback.rb +2 -2
- data/app/controllers/hubrise_app/oauth_controller/action_connect_callback.rb +3 -3
- data/app/controllers/hubrise_app/oauth_controller/action_login_callback.rb +2 -2
- data/app/controllers/hubrise_app/oauth_controller.rb +4 -2
- data/app/lib/hubrise_app/hubrise_gateway.rb +13 -1
- data/app/lib/hubrise_app/refresher/account.rb +12 -20
- data/app/lib/hubrise_app/refresher/app_instance.rb +20 -27
- 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 +10 -15
- data/app/lib/hubrise_app/refresher/user.rb +12 -12
- data/app/lib/hubrise_app/services/assign_app_instance.rb +1 -1
- data/app/lib/hubrise_app/services/connect_app_instance.rb +1 -3
- 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/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/version.rb +1 -1
- metadata +26 -11
- data/app/models/hubrise_app/hr_account.rb +0 -5
- data/app/models/hubrise_app/hr_app_instance.rb +0 -8
- data/app/models/hubrise_app/hr_location.rb +0 -5
- data/app/models/hubrise_app/hr_user.rb +0 -17
- data/app/models/hubrise_app/hr_user_app_instance.rb +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: edf33f7af21bacda62ed654f44074d3e15fc301736a31891e805650f4574fd6f
|
4
|
+
data.tar.gz: 2257043da794e990c02848bc3b4fe82434be9faa0a9f3b7264979055f1f18581
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '03943e1911fd4482d11893dc81a3d1c0b34f113523865fe62df1c54f316fc9c5b677758c57f9fc8a37049f0e8be409d3ba656cb44f1729a4d056600cb665e8bb'
|
7
|
+
data.tar.gz: e94a7836108d8f6734107e085acc429ec05f03d01165a67fc1e2b29d8670c264ca1255d91c95ce36a55a38e603122679cc8a4b5c29765ae163c6a996573d87b7
|
data/README.md
CHANGED
@@ -1,7 +1,81 @@
|
|
1
1
|

|
2
2
|
|
3
|
-
|
4
|
-
|
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
|
5
79
|
|
6
80
|
## License
|
7
81
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -1,28 +1,28 @@
|
|
1
1
|
module HubriseApp::ApplicationController::AppInstanceMethods
|
2
2
|
extend ActiveSupport::Concern
|
3
3
|
included do
|
4
|
-
helper_method :
|
4
|
+
helper_method :current_app_instance
|
5
5
|
end
|
6
6
|
|
7
7
|
def hr_app_instance_id
|
8
8
|
params[:app_instance_id]
|
9
9
|
end
|
10
10
|
|
11
|
-
def
|
12
|
-
if
|
13
|
-
@
|
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
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
17
|
+
def ensure_app_instance_found!
|
18
18
|
if hr_app_instance_id.blank?
|
19
19
|
render(plain: "Something went wrong. Please try to reopen from Hubrise Dashboard.")
|
20
|
-
elsif
|
21
|
-
redirect_to(build_hubrise_oauth_authorize_url)
|
20
|
+
elsif current_app_instance.nil?
|
21
|
+
redirect_to(build_hubrise_oauth_authorize_url, allow_other_host: true)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
25
|
def default_url_options
|
26
|
-
super.merge(app_instance_id: hr_app_instance_id ||
|
26
|
+
super.merge(app_instance_id: hr_app_instance_id || current_app_instance&.hr_id)
|
27
27
|
end
|
28
28
|
end
|
@@ -2,29 +2,29 @@ module HubriseApp::ApplicationController::SessionMethods
|
|
2
2
|
extend ActiveSupport::Concern
|
3
3
|
included do
|
4
4
|
protect_from_forgery with: :reset_session
|
5
|
-
helper_method :
|
5
|
+
helper_method :current_user, :logged_in?
|
6
6
|
end
|
7
7
|
|
8
|
-
def login(
|
9
|
-
session[:user_id] =
|
10
|
-
@
|
8
|
+
def login(user)
|
9
|
+
session[:user_id] = user.id
|
10
|
+
@current_user = user
|
11
11
|
end
|
12
12
|
|
13
13
|
def logout
|
14
14
|
session[:user_id] = nil
|
15
15
|
end
|
16
16
|
|
17
|
-
def
|
18
|
-
@
|
17
|
+
def current_user
|
18
|
+
@current_user ||= User.where(id: session[:user_id]).take
|
19
19
|
end
|
20
20
|
|
21
21
|
def logged_in?
|
22
|
-
!!
|
22
|
+
!!current_user
|
23
23
|
end
|
24
24
|
|
25
25
|
def ensure_authenticated!
|
26
26
|
unless logged_in?
|
27
|
-
redirect_to(build_hubrise_oauth_login_url)
|
27
|
+
redirect_to(build_hubrise_oauth_login_url, allow_other_host: true)
|
28
28
|
return
|
29
29
|
end
|
30
30
|
|
@@ -1,23 +1,31 @@
|
|
1
1
|
module HubriseApp
|
2
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
|
include ActionEvent
|
7
8
|
include ActionDisconnect
|
8
9
|
|
9
10
|
protected
|
10
11
|
|
11
|
-
def
|
12
|
-
HubriseApp::Services::ResolveAppInstance.run(
|
12
|
+
def current_app_instance
|
13
|
+
HubriseApp::Services::ResolveAppInstance.run(AppInstance, params[:app_instance_id], self)
|
13
14
|
end
|
14
15
|
|
15
|
-
def
|
16
|
-
head(404) unless
|
16
|
+
def ensure_app_instance_found!
|
17
|
+
head(404) unless current_app_instance
|
17
18
|
end
|
18
19
|
|
19
20
|
def event_params
|
20
|
-
params.require(:callback).permit
|
21
|
+
params.require(:callback).permit!.to_h
|
22
|
+
end
|
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
|
21
29
|
end
|
22
30
|
end
|
23
31
|
end
|
@@ -2,8 +2,8 @@ module HubriseApp::OauthController::ActionAuthorizeCallback
|
|
2
2
|
# authorize access to specific app_instance (expirable)
|
3
3
|
def authorize_callback
|
4
4
|
ensure_authenticated! do
|
5
|
-
if
|
6
|
-
HubriseApp::Services::AssignAppInstance.run(
|
5
|
+
if current_app_instance
|
6
|
+
HubriseApp::Services::AssignAppInstance.run(current_user, current_app_instance, self)
|
7
7
|
redirect_to(build_hubrise_open_url)
|
8
8
|
else
|
9
9
|
render(plain: "Something went wrong. Please try to reinstall the app")
|
@@ -1,12 +1,12 @@
|
|
1
1
|
module HubriseApp::OauthController::ActionConnectCallback
|
2
2
|
def connect_callback
|
3
|
-
@
|
3
|
+
@app_instance = HubriseApp::Services::ConnectAppInstance.run(api_client_from_oauth_code, self)
|
4
4
|
|
5
5
|
if logged_in?
|
6
|
-
HubriseApp::Services::AssignAppInstance.run(
|
6
|
+
HubriseApp::Services::AssignAppInstance.run(current_user, @app_instance, self)
|
7
7
|
redirect_to(build_hubrise_open_url)
|
8
8
|
else
|
9
|
-
redirect_to(build_hubrise_oauth_login_url)
|
9
|
+
redirect_to(build_hubrise_oauth_login_url, allow_other_host: true)
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module HubriseApp::OauthController::ActionLoginCallback
|
2
2
|
def login_callback
|
3
|
-
|
4
|
-
login(
|
3
|
+
user = HubriseApp::Refresher::User.from_api_client(api_client_from_oauth_code)
|
4
|
+
login(user)
|
5
5
|
redirect_to(build_hubrise_open_url)
|
6
6
|
end
|
7
7
|
end
|
@@ -6,8 +6,10 @@ module HubriseApp
|
|
6
6
|
|
7
7
|
protected
|
8
8
|
|
9
|
-
def
|
10
|
-
@
|
9
|
+
def current_app_instance
|
10
|
+
@app_instance ||= HubriseApp::Services::ResolveAppInstance.run(
|
11
|
+
AppInstance, api_client_from_oauth_code.app_instance_id, self
|
12
|
+
)
|
11
13
|
end
|
12
14
|
|
13
15
|
def api_client_from_oauth_code
|
@@ -21,7 +21,7 @@ class HubriseApp::HubriseGateway
|
|
21
21
|
|
22
22
|
def build_api_client_from_app_instance(app_instance)
|
23
23
|
build_api_client(
|
24
|
-
access_token: app_instance.
|
24
|
+
access_token: app_instance.access_token,
|
25
25
|
app_instance_id: app_instance.hr_id,
|
26
26
|
account_id: app_instance.hr_account_id,
|
27
27
|
location_id: app_instance.hr_location_id,
|
@@ -43,4 +43,16 @@ class HubriseApp::HubriseGateway
|
|
43
43
|
def build_app_authorization_url(hr_app_instance_id, redirect_uri)
|
44
44
|
build_api_client.build_authorization_url(redirect_uri, nil, app_instance_id: hr_app_instance_id)
|
45
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
|
+
)
|
57
|
+
end
|
46
58
|
end
|
@@ -1,23 +1,15 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
else
|
14
|
-
api_client.get_account(hr_account.hr_id).data
|
15
|
-
end.except("id")
|
16
|
-
)
|
17
|
-
end
|
18
|
-
|
19
|
-
def stale?(hr_account)
|
20
|
-
hr_account.refreshed_at.nil? || Time.now - hr_account.refreshed_at > REFRESH_THRESHOLD
|
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
|
21
13
|
end
|
22
14
|
end
|
23
15
|
end
|
@@ -1,30 +1,23 @@
|
|
1
|
-
|
2
|
-
class
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
|
-
def build_hr_location(api_client)
|
24
|
-
if api_client.location_id
|
25
|
-
hr_location = HubriseApp::HrLocation.find_or_initialize_by(hr_id: api_client.location_id)
|
26
|
-
HubriseApp::Refresher::Location.run(hr_location, api_client)
|
27
|
-
hr_location
|
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
|
28
21
|
end
|
29
22
|
end
|
30
23
|
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
|
@@ -1,18 +1,13 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
)
|
12
|
-
end
|
13
|
-
|
14
|
-
def stale?(hr_location)
|
15
|
-
hr_location.refreshed_at.nil? || Time.now - hr_location.refreshed_at > REFRESH_THRESHOLD
|
1
|
+
module HubriseApp::Refresher
|
2
|
+
class Location < Base
|
3
|
+
class << self
|
4
|
+
def fetch_attributes(resource, api_client)
|
5
|
+
{
|
6
|
+
api_data: api_client.get_location(resource.hr_id)
|
7
|
+
.data
|
8
|
+
.except("id", "account")
|
9
|
+
}
|
10
|
+
end
|
16
11
|
end
|
17
12
|
end
|
18
13
|
end
|
@@ -1,15 +1,15 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
1
|
+
module HubriseApp::Refresher
|
2
|
+
class User < Base
|
3
|
+
class << self
|
4
|
+
def fetch_attributes(resource, api_client)
|
5
|
+
api_data = api_client.get_user.data
|
6
|
+
{
|
7
|
+
access_token: api_client.access_token,
|
8
|
+
email: api_data["email"],
|
9
|
+
first_name: api_data["first_name"],
|
10
|
+
last_name: api_data["last_name"],
|
11
|
+
locales: api_data["locales"]
|
12
|
+
}
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class HubriseApp::Services::AssignAppInstance
|
2
2
|
def self.run(hr_user, hr_app_instance, _ctx)
|
3
|
-
|
3
|
+
UserAppInstance.find_or_initialize_by(
|
4
4
|
hr_app_instance_id: hr_app_instance.hr_id,
|
5
5
|
hr_user_id: hr_user.hr_id
|
6
6
|
).update!(refreshed_at: Time.now)
|
@@ -1,7 +1,5 @@
|
|
1
1
|
class HubriseApp::Services::ConnectAppInstance
|
2
2
|
def self.run(api_client, _ctx)
|
3
|
-
|
4
|
-
HubriseApp::Refresher::AppInstance.run(hr_app_instance, api_client)
|
5
|
-
hr_app_instance
|
3
|
+
HubriseApp::Refresher::AppInstance.from_api_client(api_client)
|
6
4
|
end
|
7
5
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module HubriseApp
|
2
|
+
class AppInstanceBase < HubriseApp::ApplicationRecord
|
3
|
+
self.abstract_class = true
|
4
|
+
|
5
|
+
belongs_to :account, optional: true, primary_key: :hr_id, foreign_key: :hr_account_id
|
6
|
+
belongs_to :location, optional: true, primary_key: :hr_id, foreign_key: :hr_location_id
|
7
|
+
belongs_to :catalog, optional: true, primary_key: :hr_id, foreign_key: :hr_catalog_id
|
8
|
+
belongs_to :customer_list, optional: true, primary_key: :hr_id, foreign_key: :hr_customer_list_id
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module HubriseApp
|
2
|
+
class UserAppInstanceBase < HubriseApp::ApplicationRecord
|
3
|
+
self.abstract_class = true
|
4
|
+
|
5
|
+
belongs_to :app_instance, primary_key: :hr_id, foreign_key: :hr_app_instance_id
|
6
|
+
|
7
|
+
REFRESH_THRESHOLD = 1.day
|
8
|
+
def self.fresh(time: Time.now)
|
9
|
+
where("user_app_instances.refreshed_at > ?", time - REFRESH_THRESHOLD)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module HubriseApp
|
2
|
+
class UserBase < HubriseApp::ApplicationRecord
|
3
|
+
self.abstract_class = true
|
4
|
+
|
5
|
+
has_many :user_app_instances, -> { fresh }, primary_key: :hr_id, foreign_key: :hr_user_id
|
6
|
+
has_many :app_instances, through: :user_app_instances
|
7
|
+
|
8
|
+
serialize :locales
|
9
|
+
|
10
|
+
def primary_locale
|
11
|
+
locales.first
|
12
|
+
end
|
13
|
+
|
14
|
+
def full_name
|
15
|
+
[first_name, last_name].join(" ")
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/app/models/user.rb
ADDED
@@ -1,44 +1,48 @@
|
|
1
1
|
class CreateBaseTables < ActiveRecord::Migration[5.2]
|
2
2
|
def change
|
3
|
-
create_table :
|
4
|
-
t.string
|
5
|
-
t.
|
3
|
+
create_table :accounts do |t|
|
4
|
+
t.string :hr_id, null: false, index: { unique: true }
|
5
|
+
t.string :name, null: false
|
6
|
+
t.string :currency, null: false
|
6
7
|
t.datetime :refreshed_at, null: false
|
7
8
|
end
|
8
9
|
|
9
|
-
create_table :
|
10
|
-
t.string
|
11
|
-
t.
|
10
|
+
create_table :locations do |t|
|
11
|
+
t.string :hr_id, null: false, index: { unique: true }
|
12
|
+
t.string :name, null: false
|
12
13
|
t.datetime :refreshed_at, null: false
|
13
14
|
end
|
14
15
|
|
15
|
-
create_table :
|
16
|
+
create_table :app_instances do |t|
|
16
17
|
t.string :hr_id, null: false, index: { unique: true }
|
17
|
-
t.string :hr_account_id,
|
18
|
+
t.string :hr_account_id, index: true
|
18
19
|
t.string :hr_location_id, index: true
|
19
20
|
t.string :hr_catalog_id
|
20
21
|
t.string :hr_customer_list_id
|
21
|
-
t.string :
|
22
|
+
t.string :access_token, null: false
|
22
23
|
end
|
23
24
|
|
24
|
-
add_foreign_key :
|
25
|
-
add_foreign_key :
|
25
|
+
add_foreign_key :app_instances, :accounts, primary_key: :hr_id, column: :hr_account_id
|
26
|
+
add_foreign_key :app_instances, :locations, primary_key: :hr_id, column: :hr_location_id
|
26
27
|
|
27
|
-
create_table :
|
28
|
-
t.string
|
29
|
-
t.
|
30
|
-
t.string
|
31
|
-
t.
|
28
|
+
create_table :users do |t|
|
29
|
+
t.string :hr_id, null: false, index: { unique: true }
|
30
|
+
t.string :access_token, null: false
|
31
|
+
t.string :email
|
32
|
+
t.string :first_name
|
33
|
+
t.string :last_name
|
34
|
+
t.string :locales, array: true
|
35
|
+
t.datetime :refreshed_at, null: false
|
32
36
|
end
|
33
37
|
|
34
|
-
create_table :
|
35
|
-
t.string
|
36
|
-
t.string
|
37
|
-
t.datetime
|
38
|
+
create_table :user_app_instances do |t|
|
39
|
+
t.string :hr_user_id, index: true
|
40
|
+
t.string :hr_app_instance_id, index: true
|
41
|
+
t.datetime :refreshed_at, null: false
|
38
42
|
end
|
39
43
|
|
40
|
-
add_foreign_key :
|
41
|
-
add_foreign_key :
|
42
|
-
add_index :
|
44
|
+
add_foreign_key :user_app_instances, :users, primary_key: :hr_id, column: :hr_user_id
|
45
|
+
add_foreign_key :user_app_instances, :app_instances, primary_key: :hr_id, column: :hr_app_instance_id
|
46
|
+
add_index :user_app_instances, %i[hr_user_id hr_app_instance_id refreshed_at], name: :index_user_app_instances, using: :btree
|
43
47
|
end
|
44
48
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class AddCatalogsAndCustomerLists < ActiveRecord::Migration[6.0]
|
2
|
+
def change
|
3
|
+
create_table :catalogs do |t|
|
4
|
+
t.string :hr_id, null: false
|
5
|
+
t.json :api_data
|
6
|
+
t.datetime :refreshed_at, null: false
|
7
|
+
t.index :hr_id, unique: true
|
8
|
+
end
|
9
|
+
|
10
|
+
create_table :customer_lists do |t|
|
11
|
+
t.string :hr_id, null: false
|
12
|
+
t.json :api_data
|
13
|
+
t.datetime :refreshed_at, null: false
|
14
|
+
t.index :hr_id, unique: true
|
15
|
+
end
|
16
|
+
|
17
|
+
AppInstance.distinct.pluck(:hr_catalog_id).each do |hr_catalog_id|
|
18
|
+
Catalog.create!(hr_id: hr_catalog_id, refreshed_at: Date.new(2000)) if hr_catalog_id.present?
|
19
|
+
end
|
20
|
+
|
21
|
+
AppInstance.distinct.pluck(:hr_customer_list_id).each do |hr_customer_list_id|
|
22
|
+
CustomerList.create!(hr_id: hr_customer_list_id, refreshed_at: Date.new(2000)) if hr_customer_list_id.present?
|
23
|
+
end
|
24
|
+
|
25
|
+
add_foreign_key :app_instances, :catalogs, primary_key: :hr_id, column: :hr_catalog_id
|
26
|
+
add_foreign_key :app_instances, :customer_lists, primary_key: :hr_id, column: :hr_customer_list_id
|
27
|
+
end
|
28
|
+
end
|
data/lib/hubrise_app/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hubrise_app
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Antoine Monnier
|
@@ -9,20 +9,20 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2022-05-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: hubrise_client
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
requirements:
|
18
|
-
- - "
|
18
|
+
- - "~>"
|
19
19
|
- !ruby/object:Gem::Version
|
20
20
|
version: 2.0.2
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
|
-
- - "
|
25
|
+
- - "~>"
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: 2.0.2
|
28
28
|
- !ruby/object:Gem::Dependency
|
@@ -66,22 +66,38 @@ files:
|
|
66
66
|
- app/lib/hubrise_app/hubrise_gateway.rb
|
67
67
|
- app/lib/hubrise_app/refresher/account.rb
|
68
68
|
- app/lib/hubrise_app/refresher/app_instance.rb
|
69
|
+
- app/lib/hubrise_app/refresher/base.rb
|
70
|
+
- app/lib/hubrise_app/refresher/catalog.rb
|
71
|
+
- app/lib/hubrise_app/refresher/customer_list.rb
|
69
72
|
- app/lib/hubrise_app/refresher/location.rb
|
70
73
|
- app/lib/hubrise_app/refresher/user.rb
|
71
74
|
- app/lib/hubrise_app/services/assign_app_instance.rb
|
72
75
|
- app/lib/hubrise_app/services/connect_app_instance.rb
|
73
76
|
- app/lib/hubrise_app/services/resolve_app_instance.rb
|
77
|
+
- app/models/account.rb
|
78
|
+
- app/models/app_instance.rb
|
79
|
+
- app/models/catalog.rb
|
80
|
+
- app/models/customer_list.rb
|
81
|
+
- app/models/hubrise_app/account_base.rb
|
82
|
+
- app/models/hubrise_app/app_instance_base.rb
|
74
83
|
- app/models/hubrise_app/application_record.rb
|
75
|
-
- app/models/hubrise_app/
|
76
|
-
- app/models/hubrise_app/
|
77
|
-
- app/models/hubrise_app/
|
78
|
-
- app/models/hubrise_app/
|
79
|
-
- app/models/hubrise_app/
|
84
|
+
- app/models/hubrise_app/catalog_base.rb
|
85
|
+
- app/models/hubrise_app/customer_list_base.rb
|
86
|
+
- app/models/hubrise_app/location_base.rb
|
87
|
+
- app/models/hubrise_app/user_app_instance_base.rb
|
88
|
+
- app/models/hubrise_app/user_base.rb
|
89
|
+
- app/models/location.rb
|
90
|
+
- app/models/user.rb
|
91
|
+
- app/models/user_app_instance.rb
|
80
92
|
- app/views/hubrise_app/application/root.html.haml
|
81
93
|
- app/views/layouts/hubrise_app/application.html.erb
|
82
94
|
- config/initializers/hubrise_app_config.rb
|
83
95
|
- config/routes.rb
|
84
96
|
- db/migrate/20190116155419_create_base_tables.rb
|
97
|
+
- db/migrate/20200829091933_add_locations_timezone.rb
|
98
|
+
- db/migrate/20210120142001_add_api_json_column.rb
|
99
|
+
- db/migrate/20210121150253_remove_replaced_by_api_data_columns.rb
|
100
|
+
- db/migrate/20210419120038_add_catalogs_and_customer_lists.rb
|
85
101
|
- lib/hubrise_app.rb
|
86
102
|
- lib/hubrise_app/engine.rb
|
87
103
|
- lib/hubrise_app/spec_support.rb
|
@@ -105,8 +121,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
105
121
|
- !ruby/object:Gem::Version
|
106
122
|
version: '0'
|
107
123
|
requirements: []
|
108
|
-
|
109
|
-
rubygems_version: 2.7.6.2
|
124
|
+
rubygems_version: 3.1.2
|
110
125
|
signing_key:
|
111
126
|
specification_version: 4
|
112
127
|
summary: Rails engine to bootstrap a HubRise-based application
|
@@ -1,17 +0,0 @@
|
|
1
|
-
module HubriseApp
|
2
|
-
class HrUser < HubriseApp::ApplicationRecord
|
3
|
-
self.table_name = :hr_users
|
4
|
-
|
5
|
-
has_many :hr_user_app_instances, -> { fresh }, primary_key: :hr_id
|
6
|
-
has_many :hr_app_instances, through: :hr_user_app_instances
|
7
|
-
|
8
|
-
store_accessor :hr_api_data, :first_name,
|
9
|
-
:last_name,
|
10
|
-
:email,
|
11
|
-
:locales
|
12
|
-
|
13
|
-
def primary_locale
|
14
|
-
locales&.first
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,10 +0,0 @@
|
|
1
|
-
class HubriseApp::HrUserAppInstance < HubriseApp::ApplicationRecord
|
2
|
-
self.table_name = :hr_user_app_instances
|
3
|
-
|
4
|
-
belongs_to :hr_app_instance, primary_key: :hr_id
|
5
|
-
|
6
|
-
REFRESH_THRESHOLD = 1.day
|
7
|
-
def self.fresh(time: Time.now)
|
8
|
-
where("hr_user_app_instances.refreshed_at > ?", time - REFRESH_THRESHOLD)
|
9
|
-
end
|
10
|
-
end
|