mno-enterprise-core 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +1 -0
- data/Rakefile +12 -0
- data/app/assets/images/mno_enterprise/main-logo.png +0 -0
- data/app/controllers/mno_enterprise/application_controller.rb +116 -0
- data/app/helpers/mno_enterprise/application_helper.rb +67 -0
- data/app/helpers/mno_enterprise/impersonate_helper.rb +27 -0
- data/app/models/mno_enterprise/ability.rb +6 -0
- data/app/models/mno_enterprise/app.rb +72 -0
- data/app/models/mno_enterprise/app_instance.rb +36 -0
- data/app/models/mno_enterprise/app_instances_sync.rb +6 -0
- data/app/models/mno_enterprise/arrears_situation.rb +6 -0
- data/app/models/mno_enterprise/audit_event.rb +21 -0
- data/app/models/mno_enterprise/base_resource.rb +228 -0
- data/app/models/mno_enterprise/credit_card.rb +40 -0
- data/app/models/mno_enterprise/deletion_request.rb +35 -0
- data/app/models/mno_enterprise/impac/dashboard.rb +36 -0
- data/app/models/mno_enterprise/impac/dashboard_provisioner.rb +5 -0
- data/app/models/mno_enterprise/impac/kpi.rb +9 -0
- data/app/models/mno_enterprise/impac/widget.rb +13 -0
- data/app/models/mno_enterprise/invoice.rb +53 -0
- data/app/models/mno_enterprise/org_invite.rb +50 -0
- data/app/models/mno_enterprise/organization.rb +33 -0
- data/app/models/mno_enterprise/team.rb +50 -0
- data/app/models/mno_enterprise/tenant.rb +5 -0
- data/app/models/mno_enterprise/tenant_invoice.rb +5 -0
- data/app/models/mno_enterprise/user.rb +183 -0
- data/app/pdf/mno_enterprise/invoice_pdf.rb +516 -0
- data/config/initializers/audit_log.rb +5 -0
- data/config/locales/devise.en.yml +60 -0
- data/config/routes.rb +2 -0
- data/config/styleguide.yml +106 -0
- data/lib/accountingjs_serializer.rb +51 -0
- data/lib/devise/controllers/extension_helpers.rb +52 -0
- data/lib/devise/extension_routes.rb +11 -0
- data/lib/devise/hooks/password_expirable.rb +5 -0
- data/lib/devise/models/password_expirable.rb +28 -0
- data/lib/devise/models/remote_authenticatable.rb +48 -0
- data/lib/devise/strategies/remote_authenticatable.rb +44 -0
- data/lib/devise_extension.rb +36 -0
- data/lib/faraday/adapter/net_http_no_proxy.rb +19 -0
- data/lib/generators/mno_enterprise/database_extension/USAGE +11 -0
- data/lib/generators/mno_enterprise/database_extension/database_extension_generator.rb +36 -0
- data/lib/generators/mno_enterprise/database_extension/templates/model.rb +9 -0
- data/lib/generators/mno_enterprise/dummy/dummy_generator.rb +98 -0
- data/lib/generators/mno_enterprise/dummy/templates/rails/application.rb.erb +9 -0
- data/lib/generators/mno_enterprise/dummy/templates/rails/boot.rb.erb +6 -0
- data/lib/generators/mno_enterprise/dummy/templates/rails/database.yml +22 -0
- data/lib/generators/mno_enterprise/dummy/templates/rails/routes.rb +8 -0
- data/lib/generators/mno_enterprise/dummy/templates/rails/test-env.rb +45 -0
- data/lib/generators/mno_enterprise/install/install_generator.rb +140 -0
- data/lib/generators/mno_enterprise/install/templates/Procfile +1 -0
- data/lib/generators/mno_enterprise/install/templates/config/initializers/mno_enterprise.rb +135 -0
- data/lib/generators/mno_enterprise/install/templates/config/mno_enterprise_styleguide.yml +104 -0
- data/lib/generators/mno_enterprise/install/templates/javascripts/mno_enterprise_extensions.js +7 -0
- data/lib/generators/mno_enterprise/install/templates/stylesheets/main.less_erb +25 -0
- data/lib/generators/mno_enterprise/install/templates/stylesheets/theme.less_erb +59 -0
- data/lib/generators/mno_enterprise/install/templates/stylesheets/variables.less +337 -0
- data/lib/generators/mno_enterprise/install/templates/tasks/sprites.rake +14 -0
- data/lib/generators/mno_enterprise/puma_stack/puma_stack_generator.rb +58 -0
- data/lib/generators/mno_enterprise/templates/scripts/monit/app-server.conf +8 -0
- data/lib/generators/mno_enterprise/templates/scripts/nginx/app +51 -0
- data/lib/generators/mno_enterprise/templates/scripts/puma.rb +25 -0
- data/lib/generators/mno_enterprise/templates/scripts/setup.sh +27 -0
- data/lib/generators/mno_enterprise/templates/scripts/upstart/app-web-hotrestart.conf +26 -0
- data/lib/generators/mno_enterprise/templates/scripts/upstart/app-web-server.conf +34 -0
- data/lib/generators/mno_enterprise/templates/scripts/upstart/app-web.conf +2 -0
- data/lib/generators/mno_enterprise/templates/scripts/upstart/app.conf +11 -0
- data/lib/her_extension/her_orm_adapter.rb +54 -0
- data/lib/her_extension/middleware/mnoe_api_v1_parse_json.rb +54 -0
- data/lib/her_extension/model/associations/association.rb +61 -0
- data/lib/her_extension/model/associations/association_proxy.rb +34 -0
- data/lib/her_extension/model/associations/has_many_association.rb +115 -0
- data/lib/her_extension/model/attributes.rb +43 -0
- data/lib/her_extension/model/orm.rb +59 -0
- data/lib/her_extension/model/parse.rb +40 -0
- data/lib/her_extension/model/relation.rb +92 -0
- data/lib/her_extension/validations/remote_uniqueness_validation.rb +33 -0
- data/lib/html_processor.rb +106 -0
- data/lib/mandrill_client.rb +58 -0
- data/lib/mno-enterprise-core.rb +1 -0
- data/lib/mno_enterprise/concerns.rb +4 -0
- data/lib/mno_enterprise/concerns/controllers.rb +6 -0
- data/lib/mno_enterprise/concerns/controllers/angular_csrf.rb +59 -0
- data/lib/mno_enterprise/concerns/controllers/auth.rb +9 -0
- data/lib/mno_enterprise/concerns/controllers/auth/confirmations_controller.rb +187 -0
- data/lib/mno_enterprise/concerns/controllers/auth/passwords_controller.rb +54 -0
- data/lib/mno_enterprise/concerns/controllers/auth/registrations_controller.rb +136 -0
- data/lib/mno_enterprise/concerns/controllers/auth/sessions_controller.rb +54 -0
- data/lib/mno_enterprise/concerns/controllers/auth/unlocks_controller.rb +50 -0
- data/lib/mno_enterprise/concerns/models.rb +6 -0
- data/lib/mno_enterprise/concerns/models/ability.rb +108 -0
- data/lib/mno_enterprise/concerns/models/app_instance.rb +100 -0
- data/lib/mno_enterprise/concerns/models/organization.rb +102 -0
- data/lib/mno_enterprise/core.rb +279 -0
- data/lib/mno_enterprise/database_extendable.rb +57 -0
- data/lib/mno_enterprise/engine.rb +33 -0
- data/lib/mno_enterprise/testing_support/ability_test_helper.rb +10 -0
- data/lib/mno_enterprise/testing_support/common_rake.rb +19 -0
- data/lib/mno_enterprise/testing_support/factories.rb +13 -0
- data/lib/mno_enterprise/testing_support/factories/app_instances.rb +30 -0
- data/lib/mno_enterprise/testing_support/factories/apps.rb +45 -0
- data/lib/mno_enterprise/testing_support/factories/arrears_situation.rb +14 -0
- data/lib/mno_enterprise/testing_support/factories/audit_event.rb +15 -0
- data/lib/mno_enterprise/testing_support/factories/credit_card.rb +33 -0
- data/lib/mno_enterprise/testing_support/factories/deletion_request.rb +17 -0
- data/lib/mno_enterprise/testing_support/factories/impac/dashboards.rb +15 -0
- data/lib/mno_enterprise/testing_support/factories/impac/kpis.rb +20 -0
- data/lib/mno_enterprise/testing_support/factories/impac/widgets.rb +15 -0
- data/lib/mno_enterprise/testing_support/factories/invoices.rb +51 -0
- data/lib/mno_enterprise/testing_support/factories/org_invite.rb +24 -0
- data/lib/mno_enterprise/testing_support/factories/organizations.rb +25 -0
- data/lib/mno_enterprise/testing_support/factories/team.rb +17 -0
- data/lib/mno_enterprise/testing_support/factories/tenant.rb +12 -0
- data/lib/mno_enterprise/testing_support/factories/tenant_invoice.rb +29 -0
- data/lib/mno_enterprise/testing_support/factories/users.rb +48 -0
- data/lib/mno_enterprise/testing_support/jpi_v1_test_helper.rb +49 -0
- data/lib/mno_enterprise/testing_support/mno_enterprise_api_test_helper.rb +167 -0
- data/lib/mno_enterprise/testing_support/mnoe_faraday_test_adapter.rb +173 -0
- data/lib/mno_enterprise/testing_support/organizations_shared_helpers.rb +175 -0
- data/lib/mno_enterprise/testing_support/user_action_shared.rb +47 -0
- data/lib/mno_enterprise/version.rb +3 -0
- data/lib/tasks/mno_enterprise_tasks.rake +22 -0
- data/spec/controllers/mno_enterprise/angular_csrf_spec.rb +42 -0
- data/spec/lib/her_extension/her_orm_adapter.rb +7 -0
- data/spec/lib/her_extension/model/relation_spec.rb +7 -0
- data/spec/lib/mandrill_client_spec.rb +64 -0
- data/spec/mno_enterprise_spec.rb +79 -0
- data/spec/models/mno_enterprise/app_instance_spec.rb +7 -0
- data/spec/models/mno_enterprise/app_spec.rb +62 -0
- data/spec/models/mno_enterprise/base_resource_spec.rb +28 -0
- data/spec/models/mno_enterprise/deletion_request_spec.rb +26 -0
- data/spec/models/mno_enterprise/invoice_spec.rb +7 -0
- data/spec/models/mno_enterprise/organization_spec.rb +7 -0
- data/spec/models/mno_enterprise/user_spec.rb +44 -0
- data/spec/rails_helper.rb +73 -0
- data/spec/spec_helper.rb +78 -0
- metadata +421 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
# == Schema Information
|
2
|
+
#
|
3
|
+
# Endpoint:
|
4
|
+
# - /v1/credit_cards
|
5
|
+
# - /v1/organizations/:organization_id/credit_card
|
6
|
+
#
|
7
|
+
# id :integer not null, primary key
|
8
|
+
# title :string(255)
|
9
|
+
# first_name :string(255)
|
10
|
+
# last_name :string(255)
|
11
|
+
# country :string(255)
|
12
|
+
# masked_number :string(255)
|
13
|
+
# month :integer
|
14
|
+
# year :integer
|
15
|
+
# user_id :integer
|
16
|
+
# token :string(255)
|
17
|
+
# created_at :datetime not null
|
18
|
+
# updated_at :datetime not null
|
19
|
+
# owner_id :integer
|
20
|
+
# owner_type :string(255)
|
21
|
+
# billing_address :text
|
22
|
+
# billing_city :string(255)
|
23
|
+
# billing_postcode :string(255)
|
24
|
+
# billing_country :string(255)
|
25
|
+
# duplicated :boolean default(FALSE)
|
26
|
+
#
|
27
|
+
|
28
|
+
module MnoEnterprise
|
29
|
+
class CreditCard < BaseResource
|
30
|
+
|
31
|
+
attributes :id, :created_at, :updated_at, :title, :first_name, :last_name, :country, :masked_number, :number,
|
32
|
+
:month, :year, :billing_address, :billing_city, :billing_postcode, :billing_country, :verification_value, :organization_id
|
33
|
+
|
34
|
+
#==============================================================
|
35
|
+
# Associations
|
36
|
+
#==============================================================
|
37
|
+
belongs_to :organization, class_name: 'MnoEnterprise::Organization'
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# == Schema Information
|
2
|
+
#
|
3
|
+
# Table name: deletion_requests
|
4
|
+
#
|
5
|
+
# id :integer not null, primary key
|
6
|
+
# token :string(255)
|
7
|
+
# status :string(255)
|
8
|
+
# created_at :datetime not null
|
9
|
+
# updated_at :datetime not null
|
10
|
+
#
|
11
|
+
|
12
|
+
module MnoEnterprise
|
13
|
+
class DeletionRequest < BaseResource
|
14
|
+
attributes :id, :token, :status, :user_id
|
15
|
+
|
16
|
+
#==============================================================
|
17
|
+
# Associations
|
18
|
+
#==============================================================
|
19
|
+
belongs_to :user, class_name: 'MnoEnterprise::User'
|
20
|
+
|
21
|
+
#============================================
|
22
|
+
# Instance methods
|
23
|
+
#============================================
|
24
|
+
# We want to use the token instead of the id
|
25
|
+
def to_param
|
26
|
+
self.token
|
27
|
+
end
|
28
|
+
|
29
|
+
# TODO: specs
|
30
|
+
# Freeze user acocunt and update the deletion request
|
31
|
+
def freeze_account!
|
32
|
+
self.put(operation: 'freeze')
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module MnoEnterprise
|
2
|
+
class Impac::Dashboard < BaseResource
|
3
|
+
|
4
|
+
attributes :name, :widgets_order, :organization_ids, :widgets_templates, :currency
|
5
|
+
|
6
|
+
has_many :widgets, class_name: 'MnoEnterprise::Impac::Widget', dependent: :destroy
|
7
|
+
has_many :kpis, class_name: 'MnoEnterprise::Impac::Kpi', dependent: :destroy
|
8
|
+
belongs_to :owner, polymorphic: true
|
9
|
+
|
10
|
+
#============================================
|
11
|
+
# Instance methods
|
12
|
+
#============================================
|
13
|
+
# Return the full name of this dashboard
|
14
|
+
# Currently a simple accessor to the dashboard name (used to include the company name)
|
15
|
+
def full_name
|
16
|
+
self.name
|
17
|
+
end
|
18
|
+
|
19
|
+
# Return all the organizations linked to this dashboard and to which
|
20
|
+
# the user has access
|
21
|
+
def organizations
|
22
|
+
self.organization_ids.map do |uid|
|
23
|
+
MnoEnterprise::Organization.find_by(uid: uid)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def sorted_widgets
|
28
|
+
order = self.widgets_order.map(&:to_i) | self.widgets.map{|w| w.id }
|
29
|
+
order.map { |id| self.widgets.to_a.find{ |w| w.id == id} }.compact
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_audit_event
|
33
|
+
name
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# == Schema Information
|
2
|
+
#
|
3
|
+
# Endpoint:
|
4
|
+
# - /v1/invoices
|
5
|
+
# - /v1/organizations/:organization_id/invoices
|
6
|
+
#
|
7
|
+
# id :integer not null, primary key
|
8
|
+
# price_cents :integer
|
9
|
+
# currency :string(255)
|
10
|
+
# invoicable_type :string(255)
|
11
|
+
# invoicable_id :integer
|
12
|
+
# started_at :datetime
|
13
|
+
# ended_at :datetime
|
14
|
+
# created_at :datetime not null
|
15
|
+
# updated_at :datetime not null
|
16
|
+
# paid_at :datetime
|
17
|
+
# pdf :string(255)
|
18
|
+
# payment_id :integer
|
19
|
+
# transferred_from_id :integer
|
20
|
+
# transferred_from_type :string(255)
|
21
|
+
# transferred_at :datetime
|
22
|
+
# account_transaction_id :integer
|
23
|
+
# resolver_invoice_id :integer
|
24
|
+
# resolving_invoice_id :integer
|
25
|
+
# slug :string(255)
|
26
|
+
# promo_voucher_id :integer
|
27
|
+
# tax_pips_applied :integer
|
28
|
+
# billing_address :text
|
29
|
+
# partner_invoice_id :integer
|
30
|
+
# mnoe_tenant_id :integer
|
31
|
+
#
|
32
|
+
|
33
|
+
module MnoEnterprise
|
34
|
+
class Invoice < BaseResource
|
35
|
+
#==============================================================
|
36
|
+
# Associations
|
37
|
+
#==============================================================
|
38
|
+
belongs_to :organization, class_name: 'MnoEnterprise::Organization'
|
39
|
+
|
40
|
+
# Return a label describing the time period
|
41
|
+
# this invoice covers
|
42
|
+
def period_label
|
43
|
+
return '' unless self.started_at && self.ended_at
|
44
|
+
"#{self.started_at.strftime("%b %d,%Y")} to #{self.ended_at.strftime("%b %d,%Y")}"
|
45
|
+
end
|
46
|
+
|
47
|
+
# Return true if the invoice has been paid
|
48
|
+
# false otherwise
|
49
|
+
def paid?
|
50
|
+
!self.paid_at.blank?
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# == Schema Information
|
2
|
+
#
|
3
|
+
# Endpoint:
|
4
|
+
# - /v1/org_invites
|
5
|
+
# - /v1/organizations/:organization_id/org_invites
|
6
|
+
#
|
7
|
+
# id :integer not null, primary key
|
8
|
+
# user_id :integer
|
9
|
+
# user_email :string(255)
|
10
|
+
# organization_id :integer
|
11
|
+
# referrer_id :integer
|
12
|
+
# token :string(255)
|
13
|
+
# status :string(255)
|
14
|
+
# created_at :datetime not null
|
15
|
+
# updated_at :datetime not null
|
16
|
+
# user_role :string(255)
|
17
|
+
# team_id :integer
|
18
|
+
#
|
19
|
+
|
20
|
+
module MnoEnterprise
|
21
|
+
class OrgInvite < BaseResource
|
22
|
+
scope :active, -> { where(status: 'pending') }
|
23
|
+
|
24
|
+
#==============================================================
|
25
|
+
# Associations
|
26
|
+
#==============================================================
|
27
|
+
belongs_to :user, class_name: 'MnoEnterprise::User'
|
28
|
+
belongs_to :referrer, class_name: 'MnoEnterprise::User'
|
29
|
+
belongs_to :organization, class_name: 'MnoEnterprise::Organization'
|
30
|
+
belongs_to :team, class_name: 'MnoEnterprise::Team'
|
31
|
+
|
32
|
+
# TODO: specs
|
33
|
+
# Add the user to the organization and update the status of the invite
|
34
|
+
# Add team
|
35
|
+
def accept!(user = self.user)
|
36
|
+
self.put(operation: 'accept', data: { user_id: user.id})
|
37
|
+
end
|
38
|
+
|
39
|
+
# TODO: specs
|
40
|
+
def cancel!
|
41
|
+
self.put(operation: 'cancel')
|
42
|
+
end
|
43
|
+
|
44
|
+
# TODO: specs
|
45
|
+
# Check whether the invite is expired or not
|
46
|
+
def expired?
|
47
|
+
self.status != 'pending' || self.created_at < 3.days.ago
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# == Schema Information
|
2
|
+
#
|
3
|
+
# Endpoint:
|
4
|
+
# - /v1/organizations
|
5
|
+
# - /v1/users/:user_id/organizations
|
6
|
+
#
|
7
|
+
# id :integer not null, primary key
|
8
|
+
# uid :string(255)
|
9
|
+
# name :string(255)
|
10
|
+
# created_at :datetime not null
|
11
|
+
# updated_at :datetime not null
|
12
|
+
# account_frozen :boolean default(FALSE)
|
13
|
+
# free_trial_end_at :datetime
|
14
|
+
# soa_enabled :boolean default(TRUE)
|
15
|
+
# mails :text
|
16
|
+
# logo :string(255)
|
17
|
+
# latitude :float default(0.0)
|
18
|
+
# longitude :float default(0.0)
|
19
|
+
# geo_country_code :string(255)
|
20
|
+
# geo_state_code :string(255)
|
21
|
+
# geo_city :string(255)
|
22
|
+
# geo_tz :string(255)
|
23
|
+
# geo_currency :string(255)
|
24
|
+
# meta_data :text
|
25
|
+
# industry :string(255)
|
26
|
+
# size :string(255)
|
27
|
+
#
|
28
|
+
|
29
|
+
module MnoEnterprise
|
30
|
+
class Organization < BaseResource
|
31
|
+
include MnoEnterprise::Concerns::Models::Organization
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# == Schema Information
|
2
|
+
#
|
3
|
+
# Endpoint:
|
4
|
+
# - /v1/teams
|
5
|
+
# - /v1/organizations/:organization_id/teams
|
6
|
+
#
|
7
|
+
# id :integer not null, primary key
|
8
|
+
# name :string(255)
|
9
|
+
# created_at :datetime not null
|
10
|
+
# updated_at :datetime not null
|
11
|
+
# organization_id :integer
|
12
|
+
#
|
13
|
+
|
14
|
+
module MnoEnterprise
|
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
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,183 @@
|
|
1
|
+
# == Schema Information
|
2
|
+
#
|
3
|
+
# Endpoint:
|
4
|
+
# - /v1/users
|
5
|
+
# - /v1/organizations/:organization_id/users
|
6
|
+
#
|
7
|
+
# id :string e.g.: 1
|
8
|
+
# uid :string e.g.: usr-k3j23npo
|
9
|
+
# email :string(255) default(""), not null
|
10
|
+
# authenticatable_salt :string(255) used for session authentication
|
11
|
+
# encrypted_password :string(255) default(""), not null
|
12
|
+
# reset_password_token :string(255)
|
13
|
+
# reset_password_sent_at :datetime
|
14
|
+
# remember_created_at :datetime
|
15
|
+
# sign_in_count :integer default(0)
|
16
|
+
# current_sign_in_at :datetime
|
17
|
+
# last_sign_in_at :datetime
|
18
|
+
# current_sign_in_ip :string(255)
|
19
|
+
# last_sign_in_ip :string(255)
|
20
|
+
# confirmation_token :string(255)
|
21
|
+
# confirmed_at :datetime
|
22
|
+
# confirmation_sent_at :datetime
|
23
|
+
# unconfirmed_email :string(255)
|
24
|
+
# failed_attempts :integer default(0)
|
25
|
+
# unlock_token :string(255)
|
26
|
+
# locked_at :datetime
|
27
|
+
# created_at :datetime not null
|
28
|
+
# updated_at :datetime not null
|
29
|
+
# name :string(255)
|
30
|
+
# surname :string(255)
|
31
|
+
# company :string(255)
|
32
|
+
# phone :string(255)
|
33
|
+
# phone_country_code :string(255)
|
34
|
+
# geo_country_code :string(255)
|
35
|
+
# geo_state_code :string(255)
|
36
|
+
# geo_city :string(255)
|
37
|
+
# website :string(255)
|
38
|
+
#
|
39
|
+
|
40
|
+
module MnoEnterprise
|
41
|
+
class User < BaseResource
|
42
|
+
extend Devise::Models
|
43
|
+
|
44
|
+
# Note: password and encrypted_password are write-only attributes and are never returned by
|
45
|
+
# 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
|
51
|
+
|
52
|
+
define_model_callbacks :validation #required by Devise
|
53
|
+
devise :remote_authenticatable, :registerable, :recoverable, :rememberable,
|
54
|
+
:trackable, :validatable, :lockable, :confirmable, :timeoutable, :password_expirable
|
55
|
+
|
56
|
+
#================================
|
57
|
+
# Validation
|
58
|
+
#================================
|
59
|
+
validates_uniqueness_of :email, allow_blank: true, if: :email_changed?
|
60
|
+
|
61
|
+
if Devise.password_regex
|
62
|
+
validates :password, format: { with: Devise.password_regex, message: Devise.password_regex_message }, if: :password_required?
|
63
|
+
end
|
64
|
+
|
65
|
+
#================================
|
66
|
+
# Associations
|
67
|
+
#================================
|
68
|
+
has_many :organizations, class_name: 'MnoEnterprise::Organization'
|
69
|
+
has_many :org_invites, class_name: 'MnoEnterprise::OrgInvite'
|
70
|
+
has_one :deletion_request, class_name: 'MnoEnterprise::DeletionRequest'
|
71
|
+
has_many :dashboards, class_name: 'MnoEnterprise::Impac::Dashboard'
|
72
|
+
has_many :teams, class_name: 'MnoEnterprise::Team'
|
73
|
+
|
74
|
+
#================================
|
75
|
+
# Callbacks
|
76
|
+
#================================
|
77
|
+
before_save :expire_user_cache
|
78
|
+
|
79
|
+
#================================
|
80
|
+
# Class Methods
|
81
|
+
#================================
|
82
|
+
# The auth_hash includes an email and password
|
83
|
+
# Return nil in case of failure
|
84
|
+
def self.authenticate(auth_hash)
|
85
|
+
u = self.post("user_sessions", auth_hash)
|
86
|
+
|
87
|
+
if u && u.id
|
88
|
+
u.clear_attribute_changes!
|
89
|
+
return u
|
90
|
+
end
|
91
|
+
|
92
|
+
nil
|
93
|
+
end
|
94
|
+
|
95
|
+
#================================
|
96
|
+
# Devise Confirmation
|
97
|
+
# TODO: should go in a module
|
98
|
+
#================================
|
99
|
+
|
100
|
+
|
101
|
+
# Override Devise to allow confirmation via original token
|
102
|
+
# Less secure but useful if user has been created by Maestrano Enterprise
|
103
|
+
# (happens when an orga_invite is sent to a new user)
|
104
|
+
#
|
105
|
+
# Find a user by its confirmation token and try to confirm it.
|
106
|
+
# If no user is found, returns a new user with an error.
|
107
|
+
# If the user is already confirmed, create an error for the user
|
108
|
+
# Options must have the confirmation_token
|
109
|
+
def self.confirm_by_token(confirmation_token)
|
110
|
+
confirmable = self.find_for_confirmation(confirmation_token)
|
111
|
+
confirmable.perform_confirmation(confirmation_token)
|
112
|
+
confirmable
|
113
|
+
end
|
114
|
+
|
115
|
+
# Find a user using a confirmation token
|
116
|
+
def self.find_for_confirmation(confirmation_token)
|
117
|
+
original_token = confirmation_token
|
118
|
+
confirmation_token = Devise.token_generator.digest(self, :confirmation_token, confirmation_token)
|
119
|
+
|
120
|
+
confirmable = find_or_initialize_with_error_by(:confirmation_token, confirmation_token)
|
121
|
+
confirmable = find_or_initialize_with_error_by(:confirmation_token, original_token) if confirmable.errors.any?
|
122
|
+
confirmable
|
123
|
+
end
|
124
|
+
|
125
|
+
# Confirm the user and store confirmation_token
|
126
|
+
def perform_confirmation(confirmation_token)
|
127
|
+
self.confirm if self.persisted?
|
128
|
+
self.confirmation_token = confirmation_token
|
129
|
+
end
|
130
|
+
|
131
|
+
# It may happen that that the errors attribute become nil, which breaks the controller logic (rails responder)
|
132
|
+
# This getter ensures that 'errors' is always initialized
|
133
|
+
def errors
|
134
|
+
@errors ||= ActiveModel::Errors.new(self)
|
135
|
+
end
|
136
|
+
|
137
|
+
#================================
|
138
|
+
# Instance Methods
|
139
|
+
#================================
|
140
|
+
|
141
|
+
def to_s
|
142
|
+
"#{name} #{surname}"
|
143
|
+
end
|
144
|
+
|
145
|
+
# Format for audit log
|
146
|
+
def to_audit_event
|
147
|
+
{
|
148
|
+
user_name: to_s,
|
149
|
+
user_email: email
|
150
|
+
}
|
151
|
+
end
|
152
|
+
|
153
|
+
# Default value for failed attempts
|
154
|
+
def failed_attempts
|
155
|
+
read_attribute(:failed_attempts) || 0
|
156
|
+
end
|
157
|
+
|
158
|
+
# Override Devise default method
|
159
|
+
def authenticatable_salt
|
160
|
+
read_attribute(:authenticatable_salt)
|
161
|
+
end
|
162
|
+
|
163
|
+
# Return the role of this user for the provided
|
164
|
+
# organization
|
165
|
+
def role(organization = nil)
|
166
|
+
# Return cached version if available
|
167
|
+
return self.read_attribute(:role) if !organization
|
168
|
+
|
169
|
+
org = self.organizations.to_a.find { |o| o.id.to_s == organization.id.to_s }
|
170
|
+
org ? org.role : nil
|
171
|
+
end
|
172
|
+
|
173
|
+
def expire_user_cache
|
174
|
+
Rails.cache.delete(['user', self.to_key])
|
175
|
+
true # Don't skip save if above return false (memory_store)
|
176
|
+
end
|
177
|
+
|
178
|
+
def refresh_user_cache
|
179
|
+
self.reload
|
180
|
+
Rails.cache.write(['user', self.to_key], self)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|