mno-enterprise-core 3.1.4 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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>
|