mno-enterprise-core 3.1.4 → 3.2.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/app/assets/images/mno_enterprise/logo-intuit.png +0 -0
- data/app/assets/images/mno_enterprise/main-logo.png +0 -0
- data/app/assets/stylesheets/mno_enterprise/mail.css +1 -4
- data/app/controllers/mno_enterprise/application_controller.rb +1 -1
- data/app/helpers/mno_enterprise/application_helper.rb +7 -7
- data/app/models/mno_enterprise/app.rb +12 -3
- data/app/models/mno_enterprise/app_answer.rb +13 -0
- data/app/models/mno_enterprise/app_comment.rb +10 -0
- data/app/models/mno_enterprise/app_feedback.rb +7 -0
- data/app/models/mno_enterprise/app_question.rb +9 -0
- data/app/models/mno_enterprise/app_review.rb +7 -0
- data/app/models/mno_enterprise/base_resource.rb +6 -1
- data/app/models/mno_enterprise/identity.rb +24 -0
- data/app/models/mno_enterprise/impac/alert.rb +10 -0
- data/app/models/mno_enterprise/impac/dashboard.rb +10 -11
- data/app/models/mno_enterprise/impac/kpi.rb +4 -2
- data/app/models/mno_enterprise/impac/widget.rb +4 -1
- data/app/models/mno_enterprise/team.rb +1 -33
- data/app/models/mno_enterprise/user.rb +109 -28
- data/app/views/system_notifications/email-change.html.erb +27 -0
- data/app/views/system_notifications/email-change.text.erb +10 -0
- data/app/views/system_notifications/password-change.html.erb +25 -0
- data/app/views/system_notifications/password-change.text.erb +7 -0
- data/app/views/system_notifications/reconfirmation-instructions.html.erb +7 -5
- data/app/views/system_notifications/reconfirmation-instructions.text.erb +3 -2
- data/config/initializers/config.rb +5 -0
- data/config/locales/models/user/en.yml +5 -0
- data/config/locales/templates/components/en.yml +9 -0
- data/config/locales/templates/dashboard/en.yml +14 -0
- data/config/locales/templates/dashboard/marketplace/en.yml +111 -8
- data/config/locales/templates/dashboard/organization/en.yml +1 -0
- data/config/locales/templates/impac/dock/en.yml +28 -0
- data/config/locales/views/auth/shared/en.yml +1 -2
- data/config/locales/views/webhook/o_auth/providers/en.yml +11 -6
- data/lib/devise/hooks/lockable.rb +13 -0
- data/lib/devise/models/remote_authenticatable.rb +31 -5
- data/lib/generators/mno_enterprise/install/install_generator.rb +7 -0
- data/lib/generators/mno_enterprise/install/templates/Procfile +1 -1
- data/lib/generators/mno_enterprise/install/templates/Procfile.dev +1 -1
- data/lib/generators/mno_enterprise/install/templates/config/application.yml +17 -0
- data/lib/generators/mno_enterprise/install/templates/config/initializers/mno_enterprise.rb +8 -3
- data/lib/generators/mno_enterprise/install/templates/config/newrelic.yml +46 -0
- data/lib/generators/mno_enterprise/install/templates/config/puma.rb +56 -0
- data/lib/generators/mno_enterprise/install/templates/config/settings/production.yml +1 -1
- data/lib/generators/mno_enterprise/install/templates/config/settings/uat.yml +1 -1
- data/lib/generators/mno_enterprise/install/templates/config/settings.yml +21 -0
- data/lib/generators/mno_enterprise/install/templates/stylesheets/variables.less +3 -0
- data/lib/her_extension/model/associations/association_proxy.rb +10 -6
- data/lib/mno_enterprise/concerns/controllers/auth/confirmations_controller.rb +1 -1
- data/lib/mno_enterprise/concerns/controllers/auth/omniauth_callbacks_controller.rb +203 -0
- data/lib/mno_enterprise/concerns/models/ability.rb +28 -0
- data/lib/mno_enterprise/concerns/models/app_instance.rb +22 -4
- data/lib/mno_enterprise/concerns/models/intercom_user.rb +28 -0
- data/lib/mno_enterprise/concerns/models/organization.rb +14 -1
- data/lib/mno_enterprise/concerns/models/team.rb +67 -0
- data/lib/mno_enterprise/core.rb +22 -3
- data/lib/mno_enterprise/impac_client.rb +19 -0
- data/lib/mno_enterprise/mail_adapters/mandrill_adapter.rb +4 -1
- data/lib/mno_enterprise/testing_support/factories/app_review.rb +51 -0
- data/lib/mno_enterprise/testing_support/factories/apps.rb +12 -10
- data/lib/mno_enterprise/testing_support/factories/identity.rb +9 -0
- data/lib/mno_enterprise/testing_support/factories/impac/alerts.rb +18 -0
- data/lib/mno_enterprise/testing_support/factories/impac/kpis.rb +5 -9
- data/lib/mno_enterprise/testing_support/factories/users.rb +4 -0
- data/lib/mno_enterprise/testing_support/jpi_v1_test_helper.rb +39 -0
- data/lib/mno_enterprise/testing_support/organizations_shared_helpers.rb +2 -1
- data/lib/mno_enterprise/testing_support/shared_examples/jpi_v1_admin.rb +38 -0
- data/lib/mno_enterprise/version.rb +1 -1
- data/spec/lib/devise/model/remote_authenticable_spec.rb +76 -0
- data/spec/lib/mno_enterprise/impac_client_spec.rb +31 -0
- data/spec/mno_enterprise_spec.rb +7 -8
- data/spec/models/mno_enterprise/app_spec.rb +1 -1
- data/spec/models/mno_enterprise/identity_spec.rb +39 -0
- data/spec/models/mno_enterprise/organization_spec.rb +19 -2
- data/spec/models/mno_enterprise/user_spec.rb +238 -0
- metadata +86 -22
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 04d03f902dba4992c2dcf7dfc79bcde79328f734
|
4
|
+
data.tar.gz: 7abe37f46afd67baf9b2c01aa6e71f915887e91e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f102931d14d82727074363e7492e5212005693ec5124cbf13cbaf4f6366a2bbac9b661f5f48661ec4a20b4f893a4aa7e03e2bca728738f9e728b31a4991c87fb
|
7
|
+
data.tar.gz: 504de1f76c89a3a3b8f77c4948b6a5bc47b32b16437ff02e95746584e90c5a3bbff26e2989b5ee2efa70e858b8332513f6c74388a0046ed9305e4935f2b1a5a4
|
Binary file
|
Binary file
|
@@ -1,18 +1,18 @@
|
|
1
1
|
module MnoEnterprise
|
2
2
|
module ApplicationHelper
|
3
|
-
|
3
|
+
|
4
4
|
def support_email
|
5
5
|
MnoEnterprise.support_email
|
6
6
|
end
|
7
|
-
|
7
|
+
|
8
8
|
# Re-implement Devise filter
|
9
9
|
# For some reasons the original Devise filter seems to ignore the
|
10
10
|
# mnoe prefix when using custom devise controllers
|
11
|
-
def authenticate_user!
|
11
|
+
def authenticate_user!(_favourite=nil, opts={})
|
12
12
|
redirect_to(new_user_session_path) unless current_user
|
13
13
|
true
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
# Redirect a signed in user to the confirmation
|
17
17
|
# lounge if unconfirmed
|
18
18
|
def redirect_to_lounge_if_unconfirmed
|
@@ -21,17 +21,17 @@ module MnoEnterprise
|
|
21
21
|
end
|
22
22
|
return true
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
# Redirect to signup page if user not authenticated
|
26
26
|
def authenticate_user_or_signup!
|
27
27
|
unless current_user
|
28
28
|
redirect_to new_user_registration_path
|
29
29
|
false
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
true
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
def notice_hash(notice)
|
36
36
|
return {} unless notice
|
37
37
|
# TODO: refactor
|
@@ -31,8 +31,17 @@ module MnoEnterprise
|
|
31
31
|
scope :cloud, -> { where(stack: 'cloud') }
|
32
32
|
|
33
33
|
attributes :id, :uid, :nid, :name, :description, :tiny_description, :created_at, :updated_at, :logo, :website, :slug,
|
34
|
-
|
35
|
-
|
34
|
+
:categories, :key_benefits, :key_features, :testimonials, :worldwide_usage, :tiny_description,
|
35
|
+
:popup_description, :stack, :terms_url, :pictures, :tags, :api_key, :metadata_url, :metadata, :details, :rank,
|
36
|
+
:multi_instantiable, :subcategories, :reviews, :average_rating, :running_instances_count
|
37
|
+
|
38
|
+
|
39
|
+
#================================
|
40
|
+
# Associations
|
41
|
+
#================================
|
42
|
+
has_many :reviews, class_name: 'AppReview'
|
43
|
+
has_many :feedbacks, class_name: 'AppFeedback'
|
44
|
+
has_many :questions, class_name: 'AppQuestion'
|
36
45
|
|
37
46
|
# Return the list of available categories
|
38
47
|
def self.categories(list = nil)
|
@@ -55,7 +64,7 @@ module MnoEnterprise
|
|
55
64
|
end
|
56
65
|
|
57
66
|
# Methods for appinfo flags
|
58
|
-
%w(coming_soon single_billing).each do |method|
|
67
|
+
%w(coming_soon single_billing add_on).each do |method|
|
59
68
|
define_method "#{method}?" do
|
60
69
|
appinfo.presence && appinfo[method]
|
61
70
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module MnoEnterprise
|
2
|
+
# List All Answers
|
3
|
+
# MnoEnterprise::AppAnswer.all
|
4
|
+
# Create an AppAnswer
|
5
|
+
# MnoEnterprise::AppAnswer.create(description: "This is my answer", organization_id: 3, user_id: 9, app_id: 43, question_id: 1)
|
6
|
+
|
7
|
+
# An AppAnswer belong to an AppQuestion
|
8
|
+
class AppAnswer < AppReview
|
9
|
+
attributes :question_id
|
10
|
+
|
11
|
+
belongs_to :question, class_name: 'AppQuestion', foreign_key: :question_id
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module MnoEnterprise
|
2
|
+
|
3
|
+
# Create an AppComment
|
4
|
+
# MnoEnterprise::AppComment.create(description: "description", organization_id: 3, user_id: 9, app_id: 43, feedback_id: 1)
|
5
|
+
class AppComment < AppReview
|
6
|
+
attributes :feeback_id
|
7
|
+
|
8
|
+
belongs_to :feedback, class_name: 'AppFeedback', foreign_key: :feedback_id
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module MnoEnterprise
|
2
|
+
# Create an AppQuestion
|
3
|
+
# MnoEnterprise::AppQuestion.create(description: "This is my question", organization_id: 3, user_id: 9, app_id: 43)
|
4
|
+
class AppQuestion < AppReview
|
5
|
+
belongs_to :app
|
6
|
+
|
7
|
+
scope :search, ->(search) { where("description.like" => "%#{search}%") }
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
module MnoEnterprise
|
2
|
+
class AppReview < BaseResource
|
3
|
+
attributes :id, :rating, :description, :created_at, :updated_at, :app_id, :user_id, :organization_id, :status, :parent_id, :type, :edited, :edited_by_name, :edited_by_admin_role, :edited_by_id
|
4
|
+
|
5
|
+
scope :approved, -> { where(status: 'approved') }
|
6
|
+
end
|
7
|
+
end
|
@@ -49,6 +49,11 @@ module MnoEnterprise
|
|
49
49
|
self.where(hash).limit(1).first
|
50
50
|
end
|
51
51
|
|
52
|
+
# ActiveRecord Compatibility for Her
|
53
|
+
def exists?(hash)
|
54
|
+
find_by(hash).present?
|
55
|
+
end
|
56
|
+
|
52
57
|
# ActiveRecord Compatibility for Her
|
53
58
|
# Returns the class descending directly from MnoEnterprise::BaseResource, or
|
54
59
|
# an abstract class, if any, in the inheritance hierarchy.
|
@@ -146,7 +151,7 @@ module MnoEnterprise
|
|
146
151
|
raise_record_invalid if self.errors.any?
|
147
152
|
ret
|
148
153
|
else
|
149
|
-
|
154
|
+
raise_record_invalid
|
150
155
|
end
|
151
156
|
end
|
152
157
|
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# == Schema Information
|
2
|
+
#
|
3
|
+
# Endpoint: /v1/identities
|
4
|
+
#
|
5
|
+
# id :integer not null, primary key
|
6
|
+
# user_id :integer
|
7
|
+
# provider :string(255)
|
8
|
+
# uid :string(255)
|
9
|
+
# created_at :datetime not null
|
10
|
+
# updated_at :datetime not null
|
11
|
+
#
|
12
|
+
|
13
|
+
module MnoEnterprise
|
14
|
+
class Identity < BaseResource
|
15
|
+
|
16
|
+
attributes :id, :user_id, :provider, :uid, :created_at, :updated_at
|
17
|
+
|
18
|
+
belongs_to :user, class_name: 'MnoEnterprise::User'
|
19
|
+
|
20
|
+
def self.find_for_oauth(auth)
|
21
|
+
where(uid: auth.uid, provider: auth.provider).first_or_create
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
module MnoEnterprise
|
2
|
+
class Impac::Alert < BaseResource
|
3
|
+
|
4
|
+
attributes :title, :webhook, :service, :settings, :sent
|
5
|
+
|
6
|
+
belongs_to :kpi, class_name: 'MnoEnterprise::Impac::Kpi', foreign_key: 'impac_kpi_id'
|
7
|
+
has_many :recipients, class_name: 'MnoEnterprise::User'
|
8
|
+
|
9
|
+
end
|
10
|
+
end
|
@@ -1,10 +1,10 @@
|
|
1
1
|
module MnoEnterprise
|
2
2
|
class Impac::Dashboard < BaseResource
|
3
3
|
|
4
|
-
attributes :
|
4
|
+
attributes :full_name, :widgets_order, :settings, :organization_ids, :widgets_templates, :currency
|
5
5
|
|
6
|
-
has_many :widgets, class_name: 'MnoEnterprise::Impac::Widget'
|
7
|
-
has_many :kpis, class_name: 'MnoEnterprise::Impac::Kpi'
|
6
|
+
has_many :widgets, class_name: 'MnoEnterprise::Impac::Widget'
|
7
|
+
has_many :kpis, class_name: 'MnoEnterprise::Impac::Kpi'
|
8
8
|
belongs_to :owner, polymorphic: true
|
9
9
|
|
10
10
|
#============================================
|
@@ -18,13 +18,12 @@ module MnoEnterprise
|
|
18
18
|
|
19
19
|
# Return all the organizations linked to this dashboard and to which
|
20
20
|
# the user has access
|
21
|
-
def organizations
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
order.map { |id| self.widgets.to_a.find{ |w| w.id == id} }.compact
|
21
|
+
def organizations(org_list = nil)
|
22
|
+
if org_list
|
23
|
+
org_list.to_a.select { |e| self.organization_ids.include?(e.uid) }
|
24
|
+
else
|
25
|
+
MnoEnterprise::Organization.where('uid.in' => self.organization_ids).to_a
|
26
|
+
end
|
28
27
|
end
|
29
28
|
|
30
29
|
# Filter widgets list based on config
|
@@ -39,7 +38,7 @@ module MnoEnterprise
|
|
39
38
|
end
|
40
39
|
|
41
40
|
def to_audit_event
|
42
|
-
name
|
41
|
+
{name: name}
|
43
42
|
end
|
44
43
|
end
|
45
44
|
end
|
@@ -1,9 +1,11 @@
|
|
1
1
|
module MnoEnterprise
|
2
2
|
class Impac::Kpi < BaseResource
|
3
3
|
|
4
|
-
attributes :settings, :targets, :extra_params, :endpoint, :source, :element_watched
|
4
|
+
attributes :settings, :targets, :extra_params, :endpoint, :source, :element_watched, :extra_watchables
|
5
5
|
|
6
6
|
belongs_to :dashboard, class_name: 'MnoEnterprise::Impac::Dashboard'
|
7
|
-
|
7
|
+
belongs_to :widget, class_name: 'MnoEnterprise::Impac::Widget'
|
8
|
+
has_many :alerts, class_name: 'MnoEnterprise::Impac::Alert'
|
9
|
+
|
8
10
|
end
|
9
11
|
end
|
@@ -3,10 +3,13 @@ module MnoEnterprise
|
|
3
3
|
|
4
4
|
attributes :name, :width, :widget_category, :settings
|
5
5
|
|
6
|
+
alias_attribute :endpoint, :widget_category
|
7
|
+
|
6
8
|
belongs_to :dashboard, class_name: 'MnoEnterprise::Impac::Dashboard'
|
9
|
+
has_many :kpis, class_name: 'MnoEnterprise::Impac::Kpi'
|
7
10
|
|
8
11
|
def to_audit_event
|
9
|
-
name
|
12
|
+
{name: name}
|
10
13
|
end
|
11
14
|
|
12
15
|
end
|
@@ -13,38 +13,6 @@
|
|
13
13
|
|
14
14
|
module MnoEnterprise
|
15
15
|
class Team < BaseResource
|
16
|
-
|
17
|
-
attributes :id, :name, :organization_id
|
18
|
-
|
19
|
-
#=====================================
|
20
|
-
# Associations
|
21
|
-
#=====================================
|
22
|
-
belongs_to :organization, class_name: 'MnoEnterprise::Organization'
|
23
|
-
has_many :users, class_name: 'MnoEnterprise::User'
|
24
|
-
has_many :app_instances, class_name: 'MnoEnterprise::AppInstance'
|
25
|
-
|
26
|
-
|
27
|
-
# Add a user to the team
|
28
|
-
# TODO: specs
|
29
|
-
def add_user(user)
|
30
|
-
self.users.create(id: user.id)
|
31
|
-
end
|
32
|
-
|
33
|
-
# Remove a user from the team
|
34
|
-
# TODO: specs
|
35
|
-
def remove_user(user)
|
36
|
-
self.users.destroy(id: user.id)
|
37
|
-
end
|
38
|
-
|
39
|
-
# Set the app_instance permissions of this team
|
40
|
-
# Accept a collection of hashes or an array of ids
|
41
|
-
# TODO: specs
|
42
|
-
def set_access_to(collection_or_array)
|
43
|
-
# Empty arrays do not seem to be passed in the request. Force value in this case
|
44
|
-
list = collection_or_array.empty? ? [""] : collection_or_array
|
45
|
-
self.put(data: { set_access_to: list })
|
46
|
-
self.reload
|
47
|
-
self
|
48
|
-
end
|
16
|
+
include MnoEnterprise::Concerns::Models::Team
|
49
17
|
end
|
50
18
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# == Schema Information
|
2
2
|
#
|
3
|
-
# Endpoint:
|
3
|
+
# Endpoint:
|
4
4
|
# - /v1/users
|
5
5
|
# - /v1/organizations/:organization_id/users
|
6
6
|
#
|
@@ -27,31 +27,36 @@
|
|
27
27
|
# created_at :datetime not null
|
28
28
|
# updated_at :datetime not null
|
29
29
|
# name :string(255)
|
30
|
-
# surname :string(255)
|
31
|
-
# company :string(255)
|
30
|
+
# surname :string(255)
|
31
|
+
# company :string(255)
|
32
32
|
# phone :string(255)
|
33
33
|
# phone_country_code :string(255)
|
34
34
|
# geo_country_code :string(255)
|
35
35
|
# geo_state_code :string(255)
|
36
|
-
# geo_city :string(255)
|
37
|
-
# website :string(255)
|
36
|
+
# geo_city :string(255)
|
37
|
+
# website :string(255)
|
38
|
+
# api_key :string(255)
|
39
|
+
# api_secret :string(255)
|
38
40
|
#
|
39
41
|
|
40
42
|
module MnoEnterprise
|
41
43
|
class User < BaseResource
|
44
|
+
include MnoEnterprise::Concerns::Models::IntercomUser if MnoEnterprise.intercom_enabled?
|
42
45
|
extend Devise::Models
|
43
|
-
|
46
|
+
|
44
47
|
# Note: password and encrypted_password are write-only attributes and are never returned by
|
45
48
|
# the remote API. If you are looking for a session token, use authenticatable_salt
|
46
|
-
attributes :uid, :email, :password, :current_password, :password_confirmation, :authenticatable_salt, :encrypted_password, :reset_password_token, :reset_password_sent_at,
|
47
|
-
:remember_created_at, :sign_in_count, :current_sign_in_at, :last_sign_in_at, :current_sign_in_ip,
|
48
|
-
:last_sign_in_ip, :confirmation_token, :confirmed_at, :confirmation_sent_at, :unconfirmed_email,
|
49
|
-
:failed_attempts, :unlock_token, :locked_at, :name, :surname, :company, :phone, :phone_country_code,
|
50
|
-
:geo_country_code, :geo_state_code, :geo_city, :website, :orga_on_create, :sso_session, :current_password_required, :admin_role
|
51
|
-
|
49
|
+
attributes :uid, :email, :password, :current_password, :password_confirmation, :authenticatable_salt, :encrypted_password, :reset_password_token, :reset_password_sent_at,
|
50
|
+
:remember_created_at, :sign_in_count, :current_sign_in_at, :last_sign_in_at, :current_sign_in_ip,
|
51
|
+
:last_sign_in_ip, :confirmation_token, :confirmed_at, :confirmation_sent_at, :unconfirmed_email,
|
52
|
+
:failed_attempts, :unlock_token, :locked_at, :name, :surname, :company, :phone, :phone_country_code,
|
53
|
+
:geo_country_code, :geo_state_code, :geo_city, :website, :orga_on_create, :sso_session, :current_password_required, :admin_role,
|
54
|
+
:api_key, :api_secret, :developer, :kpi_enabled, :external_id, :meta_data
|
55
|
+
|
52
56
|
define_model_callbacks :validation #required by Devise
|
53
57
|
devise :remote_authenticatable, :registerable, :recoverable, :rememberable,
|
54
|
-
:trackable, :validatable, :lockable, :confirmable, :timeoutable, :password_expirable
|
58
|
+
:trackable, :validatable, :lockable, :confirmable, :timeoutable, :password_expirable,
|
59
|
+
:omniauthable, omniauth_providers: Devise.omniauth_providers
|
55
60
|
|
56
61
|
#================================
|
57
62
|
# Validation
|
@@ -67,9 +72,12 @@ module MnoEnterprise
|
|
67
72
|
has_many :organizations, class_name: 'MnoEnterprise::Organization'
|
68
73
|
has_many :org_invites, class_name: 'MnoEnterprise::OrgInvite'
|
69
74
|
has_one :deletion_request, class_name: 'MnoEnterprise::DeletionRequest'
|
70
|
-
has_many :dashboards, class_name: 'MnoEnterprise::Impac::Dashboard'
|
71
75
|
has_many :teams, class_name: 'MnoEnterprise::Team'
|
72
76
|
|
77
|
+
# Impac
|
78
|
+
has_many :dashboards, class_name: 'MnoEnterprise::Impac::Dashboard'
|
79
|
+
has_many :alerts, class_name: 'MnoEnterprise::Impac::Alert'
|
80
|
+
|
73
81
|
#================================
|
74
82
|
# Callbacks
|
75
83
|
#================================
|
@@ -82,25 +90,26 @@ module MnoEnterprise
|
|
82
90
|
# Return nil in case of failure
|
83
91
|
def self.authenticate(auth_hash)
|
84
92
|
u = self.post("user_sessions", auth_hash)
|
85
|
-
|
93
|
+
|
86
94
|
if u && u.id
|
87
95
|
u.clear_attribute_changes!
|
88
96
|
return u
|
89
97
|
end
|
90
|
-
|
98
|
+
|
91
99
|
nil
|
92
100
|
end
|
93
|
-
|
101
|
+
|
102
|
+
|
94
103
|
#================================
|
95
104
|
# Devise Confirmation
|
96
105
|
# TODO: should go in a module
|
97
106
|
#================================
|
98
|
-
|
99
|
-
|
107
|
+
|
108
|
+
|
100
109
|
# Override Devise to allow confirmation via original token
|
101
110
|
# Less secure but useful if user has been created by Maestrano Enterprise
|
102
111
|
# (happens when an orga_invite is sent to a new user)
|
103
|
-
#
|
112
|
+
#
|
104
113
|
# Find a user by its confirmation token and try to confirm it.
|
105
114
|
# If no user is found, returns a new user with an error.
|
106
115
|
# If the user is already confirmed, create an error for the user
|
@@ -110,23 +119,23 @@ module MnoEnterprise
|
|
110
119
|
confirmable.perform_confirmation(confirmation_token)
|
111
120
|
confirmable
|
112
121
|
end
|
113
|
-
|
122
|
+
|
114
123
|
# Find a user using a confirmation token
|
115
124
|
def self.find_for_confirmation(confirmation_token)
|
116
125
|
original_token = confirmation_token
|
117
126
|
confirmation_token = Devise.token_generator.digest(self, :confirmation_token, confirmation_token)
|
118
|
-
|
127
|
+
|
119
128
|
confirmable = find_or_initialize_with_error_by(:confirmation_token, confirmation_token)
|
120
129
|
confirmable = find_or_initialize_with_error_by(:confirmation_token, original_token) if confirmable.errors.any?
|
121
130
|
confirmable
|
122
131
|
end
|
123
|
-
|
132
|
+
|
124
133
|
# Confirm the user and store confirmation_token
|
125
134
|
def perform_confirmation(confirmation_token)
|
126
135
|
self.confirm if self.persisted?
|
127
136
|
self.confirmation_token = confirmation_token
|
128
137
|
end
|
129
|
-
|
138
|
+
|
130
139
|
# It may happen that that the errors attribute become nil, which breaks the controller logic (rails responder)
|
131
140
|
# This getter ensures that 'errors' is always initialized
|
132
141
|
def errors
|
@@ -158,19 +167,28 @@ module MnoEnterprise
|
|
158
167
|
def failed_attempts
|
159
168
|
read_attribute(:failed_attempts) || 0
|
160
169
|
end
|
161
|
-
|
170
|
+
|
162
171
|
# Override Devise default method
|
163
172
|
def authenticatable_salt
|
164
173
|
read_attribute(:authenticatable_salt)
|
165
174
|
end
|
166
|
-
|
175
|
+
|
167
176
|
# Return the role of this user for the provided
|
168
177
|
# organization
|
169
178
|
def role(organization = nil)
|
170
179
|
# Return cached version if available
|
171
180
|
return self.read_attribute(:role) if !organization
|
172
|
-
|
173
|
-
|
181
|
+
|
182
|
+
# Find in arrays if organizations have been fetched
|
183
|
+
# already. Perform remote query otherwise
|
184
|
+
org = begin
|
185
|
+
if self.organizations.loaded?
|
186
|
+
self.organizations.to_a.find { |e| e.id == organization.id }
|
187
|
+
else
|
188
|
+
self.organizations.where(id: organization.id).first
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
174
192
|
org ? org.role : nil
|
175
193
|
end
|
176
194
|
|
@@ -182,6 +200,69 @@ module MnoEnterprise
|
|
182
200
|
def refresh_user_cache
|
183
201
|
self.reload
|
184
202
|
Rails.cache.write(['user', self.to_key], self)
|
203
|
+
# singleton can't be dumped / undefined method `marshal_dump' for nil
|
204
|
+
rescue TypeError, NoMethodError
|
205
|
+
expire_user_cache
|
206
|
+
end
|
207
|
+
|
208
|
+
# Used by omniauth providers to find or create users
|
209
|
+
# on maestrano
|
210
|
+
# See Auth::OmniauthCallbacksController
|
211
|
+
def self.find_for_oauth(auth, opts = {}, signed_in_resource = nil)
|
212
|
+
# Get the identity and user if they exist
|
213
|
+
identity = Identity.find_for_oauth(auth)
|
214
|
+
|
215
|
+
# If a signed_in_resource is provided it always overrides the existing user
|
216
|
+
# to prevent the identity being locked with accidentally created accounts.
|
217
|
+
# Note that this may leave zombie accounts (with no associated identity) which
|
218
|
+
# can be cleaned up at a later date.
|
219
|
+
user = signed_in_resource ? signed_in_resource : identity.user
|
220
|
+
|
221
|
+
# Create the user if needed
|
222
|
+
if user.blank? # WTF is wrong with user.nil?
|
223
|
+
# Get the existing user by email.
|
224
|
+
email = auth.info.email
|
225
|
+
user = self.where(email: email).first if email
|
226
|
+
|
227
|
+
# Create the user if it's a new registration
|
228
|
+
if user.nil?
|
229
|
+
user = create_from_omniauth(auth, opts.except(:authorized_link_to_email))
|
230
|
+
elsif auth.provider == 'intuit'
|
231
|
+
unless opts[:authorized_link_to_email] == user.email
|
232
|
+
# Intuit email is NOT a confirmed email. Therefore we need to ask the user to
|
233
|
+
# login the old fashion to make sure it is the right user!
|
234
|
+
fail(SecurityError, 'reconfirm credentials')
|
235
|
+
end
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
# Associate the identity with the user if needed
|
240
|
+
if identity.user != user
|
241
|
+
identity.user_id = user.id
|
242
|
+
identity.save!
|
243
|
+
end
|
244
|
+
user
|
245
|
+
end
|
246
|
+
|
247
|
+
# Create a new user from omniauth hash
|
248
|
+
def self.create_from_omniauth(auth, opts = {})
|
249
|
+
user = User.new(
|
250
|
+
name: auth.info.first_name.presence || auth.info.email[/(\S*)@/, 1],
|
251
|
+
surname: auth.info.last_name.presence || '',
|
252
|
+
email: auth.info.email,
|
253
|
+
password: Devise.friendly_token[0, 20],
|
254
|
+
avatar_url: auth.info.image.presence
|
255
|
+
)
|
256
|
+
|
257
|
+
# opts hash is expected to contain additional attributes
|
258
|
+
# to set on the model
|
259
|
+
user.assign_attributes(opts)
|
260
|
+
|
261
|
+
# Skip email confirmation if not from Intuit (Intuit email is NOT a confirmed email)
|
262
|
+
user.skip_confirmation! unless auth.provider == 'intuit'
|
263
|
+
user.save!
|
264
|
+
|
265
|
+
user
|
185
266
|
end
|
186
267
|
end
|
187
268
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
|
5
|
+
<%= stylesheet_link_tag('mno_enterprise/mail.css') %>
|
6
|
+
</head>
|
7
|
+
<body>
|
8
|
+
<p class="header">
|
9
|
+
<%= image_tag('mno_enterprise/main-logo.png') %>
|
10
|
+
</p>
|
11
|
+
|
12
|
+
<p>Hi <%= @info[:first_name] %></p>
|
13
|
+
|
14
|
+
<p>We received a request to change your email address in the platform to <%= @info[:unconfirmed_email] %>.</p>
|
15
|
+
|
16
|
+
<p>If you did not request an email change, contact us.</p>
|
17
|
+
|
18
|
+
<p>
|
19
|
+
Regards,<br/>
|
20
|
+
The Marketplace team
|
21
|
+
</p>
|
22
|
+
|
23
|
+
<p class="footer">
|
24
|
+
<%= @info[:company] %>
|
25
|
+
</p>
|
26
|
+
</body>
|
27
|
+
</html>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Hi <%= @info[:first_name] %>
|
2
|
+
=================================================================
|
3
|
+
|
4
|
+
We received a request to change your email address in the platform to <%= @info[:unconfirmed_email] %>.
|
5
|
+
|
6
|
+
If you did not request an email change, contact us.
|
7
|
+
|
8
|
+
|
9
|
+
Regards,
|
10
|
+
The Marketplace team
|
@@ -0,0 +1,25 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
|
5
|
+
<%= stylesheet_link_tag('mno_enterprise/mail.css') %>
|
6
|
+
</head>
|
7
|
+
<body>
|
8
|
+
<p class="header">
|
9
|
+
<%= image_tag('mno_enterprise/main-logo.png') %>
|
10
|
+
</p>
|
11
|
+
|
12
|
+
<p>Hi <%= @info[:first_name] %></p>
|
13
|
+
|
14
|
+
<p>We're contacting you to notify you that your password has been changed.</p>
|
15
|
+
|
16
|
+
<p>
|
17
|
+
Regards,<br/>
|
18
|
+
The Marketplace team
|
19
|
+
</p>
|
20
|
+
|
21
|
+
<p class="footer">
|
22
|
+
<%= @info[:company] %>
|
23
|
+
</p>
|
24
|
+
</body>
|
25
|
+
</html>
|