mno-enterprise-core 2.0.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 +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,60 @@
|
|
|
1
|
+
# Additional translations at https://github.com/plataformatec/devise/wiki/I18n
|
|
2
|
+
|
|
3
|
+
en:
|
|
4
|
+
devise:
|
|
5
|
+
confirmations:
|
|
6
|
+
confirmed: "Your email address has been successfully confirmed."
|
|
7
|
+
send_instructions: "You will receive an email with instructions for how to confirm your email address in a few minutes."
|
|
8
|
+
send_paranoid_instructions: "If your email address exists in our database and is unconfirmed, you will receive an email with instructions in a few minutes."
|
|
9
|
+
failure:
|
|
10
|
+
already_authenticated: "You are already signed in."
|
|
11
|
+
inactive: "Your account is not activated yet."
|
|
12
|
+
invalid: "Invalid %{authentication_keys} or password."
|
|
13
|
+
locked: "Your account is locked."
|
|
14
|
+
last_attempt: "You have one more attempt before your account is locked."
|
|
15
|
+
not_found_in_database: "Invalid %{authentication_keys} or password."
|
|
16
|
+
timeout: "Your session expired. Please sign in again to continue."
|
|
17
|
+
unauthenticated: "You need to sign in or sign up before continuing."
|
|
18
|
+
unconfirmed: "You have to confirm your email address before continuing."
|
|
19
|
+
mailer:
|
|
20
|
+
confirmation_instructions:
|
|
21
|
+
subject: "Confirmation instructions"
|
|
22
|
+
reset_password_instructions:
|
|
23
|
+
subject: "Reset password instructions"
|
|
24
|
+
unlock_instructions:
|
|
25
|
+
subject: "Unlock instructions"
|
|
26
|
+
omniauth_callbacks:
|
|
27
|
+
failure: "Could not authenticate you from %{kind} because \"%{reason}\"."
|
|
28
|
+
success: "Successfully authenticated from %{kind} account."
|
|
29
|
+
passwords:
|
|
30
|
+
no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided."
|
|
31
|
+
send_instructions: "You will receive an email with instructions on how to reset your password in a few minutes."
|
|
32
|
+
send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes."
|
|
33
|
+
updated: "Your password has been changed successfully. You are now signed in."
|
|
34
|
+
updated_not_active: "Your password has been changed successfully."
|
|
35
|
+
registrations:
|
|
36
|
+
destroyed: "Bye! Your account has been successfully cancelled. We hope to see you again soon."
|
|
37
|
+
signed_up: "Welcome! You have signed up successfully."
|
|
38
|
+
signed_up_but_inactive: "You have signed up successfully. However, we could not sign you in because your account is not yet activated."
|
|
39
|
+
signed_up_but_locked: "You have signed up successfully. However, we could not sign you in because your account is locked."
|
|
40
|
+
signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please follow the link to activate your account."
|
|
41
|
+
update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and follow the confirm link to confirm your new email address."
|
|
42
|
+
updated: "Your account has been updated successfully."
|
|
43
|
+
sessions:
|
|
44
|
+
signed_in: "Signed in successfully."
|
|
45
|
+
signed_out: "Signed out successfully."
|
|
46
|
+
already_signed_out: "Signed out successfully."
|
|
47
|
+
unlocks:
|
|
48
|
+
send_instructions: "You will receive an email with instructions for how to unlock your account in a few minutes."
|
|
49
|
+
send_paranoid_instructions: "If your account exists, you will receive an email with instructions for how to unlock it in a few minutes."
|
|
50
|
+
unlocked: "Your account has been unlocked successfully. Please sign in to continue."
|
|
51
|
+
errors:
|
|
52
|
+
messages:
|
|
53
|
+
already_confirmed: "was already confirmed, please try signing in"
|
|
54
|
+
confirmation_period_expired: "needs to be confirmed within %{period}, please request a new one"
|
|
55
|
+
expired: "has expired, please request a new one"
|
|
56
|
+
not_found: "not found"
|
|
57
|
+
not_locked: "was not locked"
|
|
58
|
+
not_saved:
|
|
59
|
+
one: "1 error prohibited this %{resource} from being saved:"
|
|
60
|
+
other: "%{count} errors prohibited this %{resource} from being saved:"
|
data/config/routes.rb
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#
|
|
2
|
+
# General Design Style
|
|
3
|
+
design:
|
|
4
|
+
# Whether to enable angular-material or not
|
|
5
|
+
material: false
|
|
6
|
+
|
|
7
|
+
#
|
|
8
|
+
# Color Theme Palette
|
|
9
|
+
# This section configures the overall theme. Any fine-tuning should be performed in the
|
|
10
|
+
# variable.css file
|
|
11
|
+
palette:
|
|
12
|
+
# Material colors
|
|
13
|
+
# Available palettes:
|
|
14
|
+
# red, pink, purple, deep-purple, indigo, blue, light-blue, cyan, teal, green,
|
|
15
|
+
# light-green, lime, yellow, amber, orange, deep-orange, brown, grey, blue-grey
|
|
16
|
+
#-------------------------
|
|
17
|
+
primary: blue-grey
|
|
18
|
+
accent: deep-purple
|
|
19
|
+
warn: red
|
|
20
|
+
background: grey
|
|
21
|
+
|
|
22
|
+
# Main regular colors
|
|
23
|
+
#-------------------------------------------
|
|
24
|
+
# Dashboard background color
|
|
25
|
+
bg_main_color: '#aeb5bf' # light gray
|
|
26
|
+
|
|
27
|
+
# Elements placed on top of bg-main-color
|
|
28
|
+
decorator_main_color: '#758192' # dark gray
|
|
29
|
+
|
|
30
|
+
# Elements placed on top of bg-main-color (secondary)
|
|
31
|
+
decorator_alt_color: '#977bf0' # purple
|
|
32
|
+
|
|
33
|
+
# Used for text used in the context of bg-main-color
|
|
34
|
+
text_strong_color: '#17262d' # dark blue
|
|
35
|
+
|
|
36
|
+
# Main inverse colors
|
|
37
|
+
#-------------------------------------------
|
|
38
|
+
# Background color used for dashboard menu. top banners, inverse modals
|
|
39
|
+
bg_inverse_color: '#ffffff' # white
|
|
40
|
+
|
|
41
|
+
# Background color for elements displayed on top of inverse elements
|
|
42
|
+
bg_on_bg_inverse_color: '#cacfd6' # lighter gray
|
|
43
|
+
|
|
44
|
+
# Background color used for elements on top of bg-inverse-color
|
|
45
|
+
bg_inverse_intense_color: '#17262d' # dark blue
|
|
46
|
+
|
|
47
|
+
# Design elements (lines, borders) on top of bg-inverse-color
|
|
48
|
+
decorator_inverse_color: '#977bf0' # purple
|
|
49
|
+
|
|
50
|
+
# Text used on top of bg-inverse-color such as inverse modals
|
|
51
|
+
text_inverse_color: '#17262d' # dark blue
|
|
52
|
+
|
|
53
|
+
# Color used in small/isolated elements
|
|
54
|
+
#-------------------------------------------
|
|
55
|
+
# used to reflect a positive action or point (e.g: tick icon)
|
|
56
|
+
elem_positive_color: '#d1e55c' # green
|
|
57
|
+
|
|
58
|
+
# stronger version of elem-positive-color (barely used)
|
|
59
|
+
elem_positive_flash_color: '#47ff00' # fluro-green
|
|
60
|
+
|
|
61
|
+
# used for regular design element - fits well with both main and inverse backgrounds
|
|
62
|
+
elem_cozy_color: '#977bf0' # purple
|
|
63
|
+
|
|
64
|
+
# Impac!
|
|
65
|
+
impac:
|
|
66
|
+
positive: '#3fc4ff' # light blue
|
|
67
|
+
negative: '#1de9b6' # light green
|
|
68
|
+
pool:
|
|
69
|
+
- '#1de9b6' # light green
|
|
70
|
+
- '#7c4dff' # fluro-purple
|
|
71
|
+
- '#ffc928' # yellow-orange
|
|
72
|
+
- '#3fc4ff' # light blue
|
|
73
|
+
- '#ff8e01' # fluro-orange
|
|
74
|
+
- '#c6ff00' # fluro-green
|
|
75
|
+
- '#d500fa' # fluro-purple
|
|
76
|
+
- '#ff6e41' # red-orange
|
|
77
|
+
- '#ffeb3c' # fluro-yellow
|
|
78
|
+
- '#ff1844' # fluro-pink
|
|
79
|
+
|
|
80
|
+
#
|
|
81
|
+
# General Application Layout
|
|
82
|
+
#
|
|
83
|
+
layout:
|
|
84
|
+
# Whether to display a header on public pages
|
|
85
|
+
public_page_header: false
|
|
86
|
+
|
|
87
|
+
# Which layout for the dashboard
|
|
88
|
+
dashboard_menu_orientation: 'vertical'
|
|
89
|
+
|
|
90
|
+
# Devise Configuration
|
|
91
|
+
devise:
|
|
92
|
+
# Links
|
|
93
|
+
remember_checkbox_shown: true
|
|
94
|
+
unlock_link_shown: true
|
|
95
|
+
forgot_password_link_shown: true
|
|
96
|
+
confirmation_link_shown: true
|
|
97
|
+
omniauth_link_shown: true
|
|
98
|
+
|
|
99
|
+
# User fields
|
|
100
|
+
phone_required: true
|
|
101
|
+
|
|
102
|
+
# Workflow configuration
|
|
103
|
+
workflow:
|
|
104
|
+
# Enable/Disable Signup onboarding - a series of screens guiding users through
|
|
105
|
+
# entering more details and setting their dashboard up
|
|
106
|
+
signup_onboarding: false
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module AccountingjsSerializer
|
|
2
|
+
|
|
3
|
+
def self.serialize(money)
|
|
4
|
+
{
|
|
5
|
+
'value' => money.to_f,
|
|
6
|
+
'options' => {
|
|
7
|
+
'symbol' => money.symbol,
|
|
8
|
+
'decimal' => money.decimal_mark,
|
|
9
|
+
'thousand' => money.thousands_separator,
|
|
10
|
+
'precision' => 2,
|
|
11
|
+
'format' => money.currency.symbol_first ? "%s%v" : "%v%s",
|
|
12
|
+
'subunit_symbol' => subunit_symbol(money.currency),
|
|
13
|
+
'subunit_format' => subunit_symbol_first(money.currency) ? "%s%v" : "%v%s",
|
|
14
|
+
'subunit_to_unit' => money.currency.subunit_to_unit,
|
|
15
|
+
'iso_code' => money.currency_as_string
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Return whether the subunit symbol
|
|
21
|
+
# should be first or not
|
|
22
|
+
def self.subunit_symbol_first(currency)
|
|
23
|
+
if currency.id == :cny
|
|
24
|
+
return true
|
|
25
|
+
else
|
|
26
|
+
return false
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Return the symbol of the
|
|
31
|
+
# subunit
|
|
32
|
+
def self.subunit_symbol(currency)
|
|
33
|
+
if currency.subunit
|
|
34
|
+
subunit_label = currency.subunit.downcase
|
|
35
|
+
|
|
36
|
+
if subunit_label =~ /cent/i && currency.iso_code == 'EUR'
|
|
37
|
+
subunit_label = 'ct'
|
|
38
|
+
elsif subunit_label =~ /cent/i
|
|
39
|
+
subunit_label = 'c'
|
|
40
|
+
elsif subunit_label =~ /penny/i
|
|
41
|
+
subunit_label = 'p'
|
|
42
|
+
elsif subunit_label =~ /fen/i
|
|
43
|
+
subunit_label = 20998.chr
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
return subunit_label
|
|
47
|
+
else
|
|
48
|
+
return nil
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module DeviseExtension
|
|
2
|
+
module Controllers
|
|
3
|
+
module Helpers
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
|
|
6
|
+
included do
|
|
7
|
+
before_filter :handle_password_change
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# controller instance methods
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
# lookup if an password change needed
|
|
14
|
+
def handle_password_change
|
|
15
|
+
return if warden.nil?
|
|
16
|
+
if not devise_controller? and not ignore_password_expire? and not request.format.nil? #and request.format.html?
|
|
17
|
+
Devise.mappings.keys.flatten.any? do |scope|
|
|
18
|
+
if signed_in?(scope) and warden.session(scope)['password_expired']
|
|
19
|
+
# re-check to avoid infinite loop if date changed after login attempt
|
|
20
|
+
if send(:"current_#{scope}").try(:need_change_password?)
|
|
21
|
+
session["#{scope}_return_to"] = request.original_fullpath if request.get?
|
|
22
|
+
redirect_for_password_change scope
|
|
23
|
+
return
|
|
24
|
+
else
|
|
25
|
+
warden.session(scope)[:password_expired] = false
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# redirect for password update with alert message
|
|
33
|
+
def redirect_for_password_change(scope)
|
|
34
|
+
redirect_to change_password_required_path_for(scope), :alert => 'Your password is expired. Please renew your password.'
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# path for change password
|
|
38
|
+
def change_password_required_path_for(resource_or_scope = nil)
|
|
39
|
+
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
|
40
|
+
change_path = "#{scope}_password_expired_path"
|
|
41
|
+
send(change_path)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
protected
|
|
45
|
+
|
|
46
|
+
# allow to overwrite for some special handlings
|
|
47
|
+
def ignore_password_expire?
|
|
48
|
+
false
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module ActionDispatch::Routing
|
|
2
|
+
class Mapper
|
|
3
|
+
|
|
4
|
+
protected
|
|
5
|
+
|
|
6
|
+
# route for handle expired passwords
|
|
7
|
+
def devise_password_expired(mapping, controllers)
|
|
8
|
+
resource :password_expired, only: [:show, :update], path: mapping.path_names[:password_expired], controller: controllers[:password_expired]
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'devise/hooks/password_expirable'
|
|
2
|
+
|
|
3
|
+
module Devise
|
|
4
|
+
module Models
|
|
5
|
+
module PasswordExpirable
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
# is an password change required?
|
|
9
|
+
def need_change_password?
|
|
10
|
+
if self.expire_password_after.is_a? Fixnum or self.expire_password_after.is_a? Float
|
|
11
|
+
self.password_changed_at.nil? or self.password_changed_at < self.expire_password_after.ago
|
|
12
|
+
else
|
|
13
|
+
false
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def expire_password_after
|
|
18
|
+
self.class.expire_password_after
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
module ClassMethods
|
|
24
|
+
Devise::Models.config(self, :expire_password_after)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module Devise
|
|
2
|
+
module Models
|
|
3
|
+
module RemoteAuthenticatable
|
|
4
|
+
extend ActiveSupport::Concern
|
|
5
|
+
|
|
6
|
+
#
|
|
7
|
+
# Here you do the request to the external webservice
|
|
8
|
+
#
|
|
9
|
+
# If the authentication is successful you should return
|
|
10
|
+
# a resource instance
|
|
11
|
+
#
|
|
12
|
+
# If the authentication fails you should return false
|
|
13
|
+
#
|
|
14
|
+
def remote_authentication(authentication_hash)
|
|
15
|
+
self.class.authenticate(authentication_hash) # call MnoEnterprise::User.authenticate
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
####################################
|
|
19
|
+
# Overriden methods from Devise::Models::Authenticatable
|
|
20
|
+
####################################
|
|
21
|
+
module ClassMethods
|
|
22
|
+
|
|
23
|
+
# This method is called from:
|
|
24
|
+
# Warden::SessionSerializer in devise
|
|
25
|
+
#
|
|
26
|
+
# It takes as many params as elements had the array
|
|
27
|
+
# returned in serialize_into_session
|
|
28
|
+
#
|
|
29
|
+
# Recreates a resource from session data
|
|
30
|
+
def serialize_from_session(key,salt)
|
|
31
|
+
record = Rails.cache.fetch(['user', key], expires_in: 1.minutes) do
|
|
32
|
+
to_adapter.get(key)
|
|
33
|
+
end.tap(&:clear_association_cache)
|
|
34
|
+
record if record && record.authenticatable_salt == salt
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Here you have to return and array with the data of your resource
|
|
38
|
+
# that you want to serialize into the session
|
|
39
|
+
#
|
|
40
|
+
# You might want to include some authentication data
|
|
41
|
+
def serialize_into_session(record)
|
|
42
|
+
[record.to_key, record.authenticatable_salt]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module Devise
|
|
2
|
+
module Strategies
|
|
3
|
+
class RemoteAuthenticatable < Authenticatable
|
|
4
|
+
|
|
5
|
+
# def valid?
|
|
6
|
+
# true || params[scope]
|
|
7
|
+
# end
|
|
8
|
+
|
|
9
|
+
# For an example check : https://github.com/plataformatec/devise/blob/master/lib/devise/strategies/database_authenticatable.rb
|
|
10
|
+
# Method called by warden to authenticate a resource.
|
|
11
|
+
def authenticate!
|
|
12
|
+
# authentication_hash doesn't include the password
|
|
13
|
+
auth_params = params[scope]
|
|
14
|
+
|
|
15
|
+
# mapping.to is a wrapper over the resource model
|
|
16
|
+
resource = mapping.to.new
|
|
17
|
+
|
|
18
|
+
return fail! unless resource
|
|
19
|
+
|
|
20
|
+
# remote_authentication method is defined in Devise::Models::RemoteAuthenticatable
|
|
21
|
+
#
|
|
22
|
+
# validate is a method defined in Devise::Strategies::Authenticatable. It takes
|
|
23
|
+
# a block which must return a boolean value.
|
|
24
|
+
#
|
|
25
|
+
# If the block returns true the resource will be loged in
|
|
26
|
+
# If the block returns false the authentication will fail!
|
|
27
|
+
if validate(resource){ resource = resource.remote_authentication(auth_params) }
|
|
28
|
+
success!(resource)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
Warden::Strategies.add :remote_authenticatable, Devise::Strategies::RemoteAuthenticatable
|
|
36
|
+
Devise.add_module :remote_authenticatable, strategy: true, controller: :sessions, route: :session
|
|
37
|
+
|
|
38
|
+
Warden::Manager.after_authentication do |user,auth,opts|
|
|
39
|
+
Rails.cache.delete(['user', user.to_key]) if user
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
Warden::Manager.before_logout do |user,auth,opts|
|
|
43
|
+
Rails.cache.delete(['user', user.to_key]) if user
|
|
44
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require 'devise'
|
|
2
|
+
require 'devise/models/password_expirable'
|
|
3
|
+
require 'devise/extension_routes'
|
|
4
|
+
|
|
5
|
+
module Devise
|
|
6
|
+
# Should the password expire (e.g 3.months)
|
|
7
|
+
mattr_accessor :expire_password_after
|
|
8
|
+
@@expire_password_after = 3.months
|
|
9
|
+
|
|
10
|
+
# Validate password strength
|
|
11
|
+
mattr_accessor :password_regex
|
|
12
|
+
@@password_regex = nil
|
|
13
|
+
# Need 1 char of A-Z, a-z and 0-9
|
|
14
|
+
# @@password_regex = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z])/
|
|
15
|
+
|
|
16
|
+
mattr_accessor :password_regex_message
|
|
17
|
+
@@password_regex_message = 'must contains at least one uppercase letter, one lower case letter and a number'
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# an security extension for devise
|
|
21
|
+
module DeviseExtension
|
|
22
|
+
module Controllers
|
|
23
|
+
autoload :Helpers, 'devise/controllers/extension_helpers'
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# modules
|
|
28
|
+
Devise.add_module :password_expirable, controller: :password_expirable, model: 'devise/models/password_expirable', route: :password_expired
|
|
29
|
+
|
|
30
|
+
module DeviseExtension
|
|
31
|
+
class Engine < ::Rails::Engine
|
|
32
|
+
ActiveSupport.on_load(:action_controller) do
|
|
33
|
+
include DeviseExtension::Controllers::Helpers
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|