incline 0.1.5
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/.gitignore +13 -0
- data/Gemfile +17 -0
- data/Gemfile.lock +186 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +208 -0
- data/Rakefile +37 -0
- data/app/assets/fonts/incline/.keep +0 -0
- data/app/assets/images/incline/.keep +0 -0
- data/app/assets/images/incline/barcode-B.svg +181 -0
- data/app/assets/javascripts/incline/activate_classed_items.js +11 -0
- data/app/assets/javascripts/incline/application.js +30 -0
- data/app/assets/javascripts/incline/bootstrap-datepicker.js +1800 -0
- data/app/assets/javascripts/incline/datatables.js +22193 -0
- data/app/assets/javascripts/incline/escapeHtml.js +10 -0
- data/app/assets/javascripts/incline/inline_actions.js +479 -0
- data/app/assets/javascripts/incline/jquery.doubleScroll.js +112 -0
- data/app/assets/javascripts/incline/jquery.number.js +764 -0
- data/app/assets/javascripts/incline/regexMask.js +27 -0
- data/app/assets/javascripts/incline/select2/i18n/en.js +3 -0
- data/app/assets/javascripts/incline/select2/select2.full.js +6436 -0
- data/app/assets/stylesheets/incline/application.css +18 -0
- data/app/assets/stylesheets/incline/bootstrap-theme.min.css +5 -0
- data/app/assets/stylesheets/incline/custom.scss +279 -0
- data/app/assets/stylesheets/incline/datatables.css +494 -0
- data/app/assets/stylesheets/incline/datepicker3.css +790 -0
- data/app/assets/stylesheets/incline/select2.css +484 -0
- data/app/controllers/incline/access_groups_controller.rb +127 -0
- data/app/controllers/incline/access_test_controller.rb +30 -0
- data/app/controllers/incline/account_activations_controller.rb +28 -0
- data/app/controllers/incline/application_controller.rb +11 -0
- data/app/controllers/incline/contact_controller.rb +34 -0
- data/app/controllers/incline/password_resets_controller.rb +113 -0
- data/app/controllers/incline/security_controller.rb +100 -0
- data/app/controllers/incline/sessions_controller.rb +50 -0
- data/app/controllers/incline/users_controller.rb +304 -0
- data/app/controllers/incline/welcome_controller.rb +19 -0
- data/app/helpers/incline/.keep +0 -0
- data/app/mailers/incline/application_mailer_base.rb +11 -0
- data/app/mailers/incline/contact_form.rb +19 -0
- data/app/mailers/incline/user_mailer.rb +45 -0
- data/app/models/incline/access_group.rb +121 -0
- data/app/models/incline/access_group_group_member.rb +12 -0
- data/app/models/incline/access_group_user_member.rb +10 -0
- data/app/models/incline/action_group.rb +12 -0
- data/app/models/incline/action_security.rb +222 -0
- data/app/models/incline/contact_message.rb +37 -0
- data/app/models/incline/disable_info.rb +20 -0
- data/app/models/incline/password_reset.rb +14 -0
- data/app/models/incline/password_reset_request.rb +14 -0
- data/app/models/incline/user.rb +437 -0
- data/app/models/incline/user_login_history.rb +30 -0
- data/app/views/incline/access_groups/_details.json.jbuilder +10 -0
- data/app/views/incline/access_groups/_form.html.erb +19 -0
- data/app/views/incline/access_groups/_list.html.erb +60 -0
- data/app/views/incline/access_groups/_messages.json.jbuilder +6 -0
- data/app/views/incline/access_groups/edit.html.erb +2 -0
- data/app/views/incline/access_groups/index.html.erb +6 -0
- data/app/views/incline/access_groups/index.json.jbuilder +16 -0
- data/app/views/incline/access_groups/new.html.erb +2 -0
- data/app/views/incline/access_groups/show.html.erb +9 -0
- data/app/views/incline/access_groups/show.json.jbuilder +11 -0
- data/app/views/incline/contact/new.html.erb +22 -0
- data/app/views/incline/contact_form/contact.html.erb +16 -0
- data/app/views/incline/contact_form/contact.text.erb +13 -0
- data/app/views/incline/password_resets/edit.html.erb +16 -0
- data/app/views/incline/password_resets/new.html.erb +12 -0
- data/app/views/incline/security/_details.json.jbuilder +7 -0
- data/app/views/incline/security/_form.html.erb +20 -0
- data/app/views/incline/security/_list.html.erb +89 -0
- data/app/views/incline/security/_messages.json.jbuilder +6 -0
- data/app/views/incline/security/edit.html.erb +2 -0
- data/app/views/incline/security/index.html.erb +6 -0
- data/app/views/incline/security/index.json.jbuilder +16 -0
- data/app/views/incline/security/show.html.erb +31 -0
- data/app/views/incline/security/show.json.jbuilder +11 -0
- data/app/views/incline/sessions/new.html.erb +26 -0
- data/app/views/incline/user_mailer/account_activation.html.erb +7 -0
- data/app/views/incline/user_mailer/account_activation.text.erb +6 -0
- data/app/views/incline/user_mailer/invalid_password_reset.html.erb +3 -0
- data/app/views/incline/user_mailer/invalid_password_reset.text.erb +5 -0
- data/app/views/incline/user_mailer/password_reset.html.erb +8 -0
- data/app/views/incline/user_mailer/password_reset.text.erb +7 -0
- data/app/views/incline/users/_details.json.jbuilder +32 -0
- data/app/views/incline/users/_form.html.erb +21 -0
- data/app/views/incline/users/_list.html.erb +102 -0
- data/app/views/incline/users/_messages.json.jbuilder +6 -0
- data/app/views/incline/users/disable_confirm.html.erb +19 -0
- data/app/views/incline/users/edit.html.erb +5 -0
- data/app/views/incline/users/index.html.erb +6 -0
- data/app/views/incline/users/index.json.jbuilder +16 -0
- data/app/views/incline/users/new.html.erb +5 -0
- data/app/views/incline/users/show.html.erb +12 -0
- data/app/views/incline/users/show.json.jbuilder +11 -0
- data/app/views/incline/welcome/home.html.erb +5 -0
- data/app/views/layouts/application.html.erb +1 -0
- data/app/views/layouts/incline/_account_menu.html.erb +18 -0
- data/app/views/layouts/incline/_app_menu_anon.html.erb +1 -0
- data/app/views/layouts/incline/_app_menu_authenticated.html.erb +1 -0
- data/app/views/layouts/incline/_footer.html.erb +13 -0
- data/app/views/layouts/incline/_header.html.erb +21 -0
- data/app/views/layouts/incline/_html_mailer.html.erb +5 -0
- data/app/views/layouts/incline/_incline_app.html.erb +25 -0
- data/app/views/layouts/incline/_messages.html.erb +3 -0
- data/app/views/layouts/incline/_shim.html.erb +3 -0
- data/app/views/layouts/incline/_text_mailer.text.erb +1 -0
- data/app/views/layouts/incline/application.html.erb +1 -0
- data/app/views/layouts/mailer.html.erb +2 -0
- data/app/views/layouts/mailer.text.erb +2 -0
- data/bin/rails +12 -0
- data/bin/test_scaffold.sh +10 -0
- data/config/routes.rb +61 -0
- data/db/migrate/20170511230126_create_incline_users.rb +26 -0
- data/db/migrate/20170515003052_create_incline_access_groups.rb +10 -0
- data/db/migrate/20170515003221_create_incline_user_login_histories.rb +12 -0
- data/db/migrate/20170515150908_create_incline_access_group_user_members.rb +11 -0
- data/db/migrate/20170515151058_create_incline_access_group_group_members.rb +11 -0
- data/db/migrate/20170517193432_add_comments_to_incline_user.rb +5 -0
- data/db/migrate/20170622132700_create_incline_action_securities.rb +16 -0
- data/db/migrate/20170622172712_create_incline_action_groups.rb +11 -0
- data/db/migrate/20170622195742_add_non_standard_to_action_security.rb +5 -0
- data/db/migrate/20170622230422_add_visible_to_action_security.rb +5 -0
- data/db/seeds.rb +81 -0
- data/exe/new_incline_app +42 -0
- data/lib/generators/incline/install_generator.rb +259 -0
- data/lib/generators/incline/templates/_app_menu_anon.html.erb +1 -0
- data/lib/generators/incline/templates/_app_menu_authenticated.html.erb +1 -0
- data/lib/generators/incline/templates/incline_application.css +17 -0
- data/lib/generators/incline/templates/incline_application.html.erb +1 -0
- data/lib/generators/incline/templates/incline_application.js +12 -0
- data/lib/generators/incline/templates/incline_database.yml +25 -0
- data/lib/generators/incline/templates/incline_email.yml +20 -0
- data/lib/generators/incline/templates/incline_mailer.html.erb +2 -0
- data/lib/generators/incline/templates/incline_mailer.text.erb +2 -0
- data/lib/generators/incline/templates/incline_users.yml +64 -0
- data/lib/generators/incline/templates/incline_version.rb +3 -0
- data/lib/incline/auth_engine_base.rb +52 -0
- data/lib/incline/data_tables_request.rb +336 -0
- data/lib/incline/date_time_formats.rb +6 -0
- data/lib/incline/engine.rb +212 -0
- data/lib/incline/errors.rb +15 -0
- data/lib/incline/extensions/action_controller_base.rb +526 -0
- data/lib/incline/extensions/action_mailer_base.rb +66 -0
- data/lib/incline/extensions/action_view_base.rb +489 -0
- data/lib/incline/extensions/active_record_base.rb +308 -0
- data/lib/incline/extensions/application.rb +137 -0
- data/lib/incline/extensions/application_configuration.rb +50 -0
- data/lib/incline/extensions/connection_adapter.rb +55 -0
- data/lib/incline/extensions/date_time_value.rb +123 -0
- data/lib/incline/extensions/date_value.rb +77 -0
- data/lib/incline/extensions/decimal_value.rb +55 -0
- data/lib/incline/extensions/erb_scaffold_generator.rb +31 -0
- data/lib/incline/extensions/float_value.rb +59 -0
- data/lib/incline/extensions/form_builder.rb +617 -0
- data/lib/incline/extensions/integer_value.rb +54 -0
- data/lib/incline/extensions/jbuilder_generator.rb +38 -0
- data/lib/incline/extensions/jbuilder_template.rb +39 -0
- data/lib/incline/extensions/main_app.rb +40 -0
- data/lib/incline/extensions/numeric.rb +63 -0
- data/lib/incline/extensions/object.rb +31 -0
- data/lib/incline/extensions/resource_route_generator.rb +53 -0
- data/lib/incline/extensions/session.rb +113 -0
- data/lib/incline/extensions/string.rb +50 -0
- data/lib/incline/extensions/test_case.rb +764 -0
- data/lib/incline/extensions/time_zone_converter.rb +40 -0
- data/lib/incline/global_status.rb +236 -0
- data/lib/incline/helpers/route_hash_formatter.rb +46 -0
- data/lib/incline/json_log_formatter.rb +96 -0
- data/lib/incline/json_logger.rb +17 -0
- data/lib/incline/log.rb +153 -0
- data/lib/incline/number_formats.rb +17 -0
- data/lib/incline/recaptcha.rb +346 -0
- data/lib/incline/user_manager.rb +212 -0
- data/lib/incline/validators/email_validator.rb +45 -0
- data/lib/incline/validators/ip_address_validator.rb +32 -0
- data/lib/incline/validators/recaptcha_validator.rb +37 -0
- data/lib/incline/validators/safe_name_validator.rb +31 -0
- data/lib/incline/version.rb +3 -0
- data/lib/incline/work_path.rb +75 -0
- data/lib/incline.rb +197 -0
- data/lib/tasks/incline_tasks.rake +4 -0
- data/lib/templates/erb/scaffold/_form.html.erb +43 -0
- data/lib/templates/erb/scaffold/_list.html.erb +81 -0
- data/lib/templates/erb/scaffold/edit.html.erb +1 -0
- data/lib/templates/erb/scaffold/index.html.erb +6 -0
- data/lib/templates/erb/scaffold/new.html.erb +1 -0
- data/lib/templates/erb/scaffold/show.html.erb +34 -0
- data/lib/templates/jbuilder/scaffold/_details.json.jbuilder +20 -0
- data/lib/templates/jbuilder/scaffold/index.json.jbuilder +16 -0
- data/lib/templates/jbuilder/scaffold/show.json.jbuilder +16 -0
- data/lib/templates/rails/scaffold_controller/controller.rb +128 -0
- data/test/controllers/incline/access_groups_controller_test.rb +65 -0
- data/test/controllers/incline/access_test_controller_test.rb +53 -0
- data/test/controllers/incline/contact_controller_test.rb +32 -0
- data/test/controllers/incline/security_controller_test.rb +39 -0
- data/test/controllers/incline/welcome_controller_test.rb +16 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/images/.keep +0 -0
- data/test/dummy/app/assets/javascripts/application.js +12 -0
- data/test/dummy/app/assets/stylesheets/application.css +17 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/controllers/concerns/.keep +0 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/mailers/.keep +0 -0
- data/test/dummy/app/models/.keep +0 -0
- data/test/dummy/app/models/concerns/.keep +0 -0
- data/test/dummy/app/views/layouts/application.html.erb +1 -0
- data/test/dummy/app/views/layouts/incline/_app_menu_anon.html.erb +1 -0
- data/test/dummy/app/views/layouts/incline/_app_menu_authenticated.html.erb +1 -0
- data/test/dummy/app/views/layouts/mailer.html.erb +2 -0
- data/test/dummy/app/views/layouts/mailer.text.erb +2 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +29 -0
- data/test/dummy/config/application.rb +38 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/database.yml +34 -0
- data/test/dummy/config/email.yml +24 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +45 -0
- data/test/dummy/config/environments/production.rb +85 -0
- data/test/dummy/config/environments/test.rb +44 -0
- data/test/dummy/config/initializers/assets.rb +11 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/to_time_preserves_timezone.rb +10 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +6 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/db/schema.rb +108 -0
- data/test/dummy/lib/assets/.keep +0 -0
- data/test/dummy/log/.keep +0 -0
- data/test/dummy/public/404.html +67 -0
- data/test/dummy/public/422.html +67 -0
- data/test/dummy/public/500.html +66 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/extensions/action_controller_base_extensions_test.rb +21 -0
- data/test/extensions/action_mailer_base_extensions_test.rb +20 -0
- data/test/extensions/action_view_base_extensions_test.rb +267 -0
- data/test/extensions/active_record_extensions_test.rb +173 -0
- data/test/extensions/application_configuration_extensions_test.rb +46 -0
- data/test/extensions/application_extensions_test.rb +23 -0
- data/test/extensions/connection_adapter_extensions_test.rb +54 -0
- data/test/extensions/date_time_value_extensions_test.rb +104 -0
- data/test/extensions/date_value_extensions_test.rb +102 -0
- data/test/extensions/decimal_value_extensions_test.rb +85 -0
- data/test/extensions/erb_scaffold_generator_extensions_test.rb +17 -0
- data/test/extensions/float_value_extensions_test.rb +78 -0
- data/test/extensions/form_builder_extensions_test.rb +28 -0
- data/test/extensions/integer_value_extensions_test.rb +78 -0
- data/test/extensions/jbuilder_generator_extensions_test.rb +21 -0
- data/test/extensions/jbuilder_template_extensions_test.rb +47 -0
- data/test/extensions/main_app_extensions_test.rb +55 -0
- data/test/extensions/numeric_extensions_test.rb +76 -0
- data/test/extensions/object_extensions_test.rb +104 -0
- data/test/extensions/session_extensions_test.rb +69 -0
- data/test/extensions/string_extensions_test.rb +32 -0
- data/test/extensions/test_case_extensions_test.rb +538 -0
- data/test/extensions/time_zone_converter_extensions_test.rb +10 -0
- data/test/fixtures/incline/access_group_group_members.yml +1 -0
- data/test/fixtures/incline/access_group_user_members.yml +1 -0
- data/test/fixtures/incline/access_groups.yml +13 -0
- data/test/fixtures/incline/action_groups.yml +6 -0
- data/test/fixtures/incline/action_securities.yml +18 -0
- data/test/fixtures/incline/user_login_histories.yml +1 -0
- data/test/fixtures/incline/users.yml +64 -0
- data/test/incline_test.rb +63 -0
- data/test/integration/incline/users_edit_test.rb +180 -0
- data/test/integration/incline/users_login_test.rb +105 -0
- data/test/integration/incline/users_signup_test.rb +147 -0
- data/test/integration/navigation_test.rb +11 -0
- data/test/lib/data_tables_request_test.rb +245 -0
- data/test/lib/date_time_formats_test.rb +111 -0
- data/test/lib/global_status_test.rb +89 -0
- data/test/lib/json_log_formatter_test.rb +43 -0
- data/test/lib/log_test.rb +36 -0
- data/test/lib/recaptcha_test.rb +75 -0
- data/test/lib/user_manager_test.rb +47 -0
- data/test/lib/work_path_test.rb +18 -0
- data/test/models/incline/access_group_group_member_test.rb +30 -0
- data/test/models/incline/access_group_test.rb +60 -0
- data/test/models/incline/access_group_user_member_test.rb +29 -0
- data/test/models/incline/action_group_test.rb +27 -0
- data/test/models/incline/action_security_test.rb +176 -0
- data/test/models/incline/contact_message_test.rb +66 -0
- data/test/models/incline/disable_info_test.rb +29 -0
- data/test/models/incline/password_reset_request_test.rb +35 -0
- data/test/models/incline/password_reset_test.rb +51 -0
- data/test/models/incline/user_login_history_test.rb +31 -0
- data/test/models/incline/user_test.rb +91 -0
- data/test/test_helper.rb +42 -0
- data/test/validators/email_validator_test.rb +102 -0
- data/test/validators/ip_address_validator_test.rb +107 -0
- data/test/validators/recaptcha_validator_test.rb +57 -0
- data/test/validators/safe_name_validator_test.rb +101 -0
- metadata +584 -0
|
@@ -0,0 +1,526 @@
|
|
|
1
|
+
require 'action_controller'
|
|
2
|
+
|
|
3
|
+
module Incline::Extensions
|
|
4
|
+
|
|
5
|
+
##
|
|
6
|
+
# Adds some extra functionality to the base controller definition.
|
|
7
|
+
module ActionControllerBase
|
|
8
|
+
|
|
9
|
+
##
|
|
10
|
+
# Adds some class methods to the base action controller.
|
|
11
|
+
module ClassMethods
|
|
12
|
+
|
|
13
|
+
##
|
|
14
|
+
# Turn on auto API for the controller.
|
|
15
|
+
def enable_auto_api
|
|
16
|
+
@enable_auto_api = true
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
##
|
|
20
|
+
# Turn off auto API for the controller.
|
|
21
|
+
def disable_auto_api
|
|
22
|
+
@enable_auto_api = false
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
##
|
|
26
|
+
# Determines if the controller is configured for auto API.
|
|
27
|
+
def auto_api?
|
|
28
|
+
@enable_auto_api ||= false
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
##
|
|
32
|
+
# Enables or disables HTTP (non-SSL) for actions.
|
|
33
|
+
#
|
|
34
|
+
# Pass +false+ to disable HTTP for all actions(default).
|
|
35
|
+
# Pass +true+ to enable HTTP for all actions.
|
|
36
|
+
# Pass action names to enable HTTP for specific actions.
|
|
37
|
+
#
|
|
38
|
+
# With no arguments, the current setting is returned.
|
|
39
|
+
#
|
|
40
|
+
# allow_non_ssl false
|
|
41
|
+
# allow_non_ssl true
|
|
42
|
+
# allow_non_ssl :home, :about
|
|
43
|
+
#
|
|
44
|
+
def allow_non_ssl(*args)
|
|
45
|
+
if args.blank?
|
|
46
|
+
@allow_non_ssl ||= false
|
|
47
|
+
else
|
|
48
|
+
@allow_non_ssl = setting_value(args)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
##
|
|
53
|
+
# Enables anonymous access for actions.
|
|
54
|
+
#
|
|
55
|
+
# Pass +false+ to disable anonymous access for all actions(default).
|
|
56
|
+
# Pass +true+ to allow anonymous access for all actions.
|
|
57
|
+
# Pass action names to enable anonymous access for specific actions.
|
|
58
|
+
#
|
|
59
|
+
# With no arguments, the current setting is returned.
|
|
60
|
+
#
|
|
61
|
+
# allow_anon false
|
|
62
|
+
# allow_anon true
|
|
63
|
+
# allow_anon :home, :about
|
|
64
|
+
#
|
|
65
|
+
def allow_anon(*args)
|
|
66
|
+
if args.blank?
|
|
67
|
+
@allow_anon ||= false
|
|
68
|
+
else
|
|
69
|
+
@allow_anon = setting_value(args)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
##
|
|
74
|
+
# Enables requiring a system administrator for actions.
|
|
75
|
+
#
|
|
76
|
+
# Pass +false+ to allow non-system administrators access for all actions(default).
|
|
77
|
+
# Pass +true+ to require system administrators for all actions.
|
|
78
|
+
# Pass action names to require system administrators for specific actions.
|
|
79
|
+
#
|
|
80
|
+
# With no arguments, the current setting is returned.
|
|
81
|
+
#
|
|
82
|
+
# require_admin false
|
|
83
|
+
# require_admin true
|
|
84
|
+
# require_admin :new, :edit, :create, :update, :destroy
|
|
85
|
+
#
|
|
86
|
+
def require_admin(*args)
|
|
87
|
+
if args.blank?
|
|
88
|
+
@require_admin ||= false
|
|
89
|
+
else
|
|
90
|
+
@require_admin = setting_value(args)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
##
|
|
95
|
+
# Enables requiring an anonymous user for actions.
|
|
96
|
+
#
|
|
97
|
+
# Pass +false+ to allow logged in users access for all actions(default).
|
|
98
|
+
# Pass +true+ to require anonymous users for all actions.
|
|
99
|
+
# Pass action names to require anonymous for specific actions.
|
|
100
|
+
#
|
|
101
|
+
# With no arguments, the current setting is returned.
|
|
102
|
+
#
|
|
103
|
+
# require_anon false
|
|
104
|
+
# require_anon true
|
|
105
|
+
# require_anon :new, :edit, :create, :update, :destroy
|
|
106
|
+
#
|
|
107
|
+
def require_anon(*args)
|
|
108
|
+
if args.blank?
|
|
109
|
+
@require_anon ||= false
|
|
110
|
+
else
|
|
111
|
+
@require_anon = setting_value(args)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
##
|
|
116
|
+
# Determines if the current request can be allowed with an anonymous user.
|
|
117
|
+
#
|
|
118
|
+
# Overridden by require_admin_for_request?
|
|
119
|
+
# Implied by require_anon_for_request?
|
|
120
|
+
def allow_anon_for?(action)
|
|
121
|
+
require_anon_for?(action) || setting_for_action(allow_anon, action)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
##
|
|
125
|
+
# Determines if the current request requires a system administrator.
|
|
126
|
+
#
|
|
127
|
+
# Overrides all other access requirements.
|
|
128
|
+
def require_admin_for?(action)
|
|
129
|
+
setting_for_action require_admin, action
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
##
|
|
133
|
+
# Determines if the current request requires an anonymous user.
|
|
134
|
+
#
|
|
135
|
+
# Overridden by require_admin_for_request?
|
|
136
|
+
# Implies allow_anon_for_request?
|
|
137
|
+
def require_anon_for?(action)
|
|
138
|
+
setting_for_action require_anon, action
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
private
|
|
142
|
+
|
|
143
|
+
def setting_value(args)
|
|
144
|
+
if args.include?(false)
|
|
145
|
+
false
|
|
146
|
+
elsif args.include?(true)
|
|
147
|
+
true
|
|
148
|
+
else
|
|
149
|
+
args.map{|v| v.is_a?(::Symbol) ? v : v.to_s.to_sym }
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def setting_for_action(setting, action)
|
|
154
|
+
return false unless setting
|
|
155
|
+
if setting.is_a?(::Array)
|
|
156
|
+
return false unless setting.include?(action.to_sym)
|
|
157
|
+
end
|
|
158
|
+
true
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
##
|
|
164
|
+
# Enforces SSL and catches Incline::NotLoggedIn exceptions.
|
|
165
|
+
def self.included(base)
|
|
166
|
+
base.extend ClassMethods
|
|
167
|
+
base.class_eval do
|
|
168
|
+
|
|
169
|
+
# Force SSL under production environments unless allow_http_for_request returns true.
|
|
170
|
+
if Rails.env.production?
|
|
171
|
+
force_ssl unless: :allow_http_for_request?
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# Process user authorization for all actions except the GET/POST api actions.
|
|
175
|
+
# These get to be authorized once the actual action is selected.
|
|
176
|
+
before_action :valid_user?, except: [ :api ]
|
|
177
|
+
|
|
178
|
+
undef process_action
|
|
179
|
+
|
|
180
|
+
##
|
|
181
|
+
# Override the default to enable auto-api behavior if desired.
|
|
182
|
+
def process_action(method_name, *args) #:nodoc:
|
|
183
|
+
if self.class.auto_api?
|
|
184
|
+
unless process_api_action(false, nil)
|
|
185
|
+
super method_name, *args
|
|
186
|
+
end
|
|
187
|
+
else
|
|
188
|
+
super method_name, *args
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
rescue_from ::Incline::NotLoggedIn do |exception|
|
|
193
|
+
flash[:info] = exception.message
|
|
194
|
+
store_location
|
|
195
|
+
redirect_to(incline.login_url)
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
##
|
|
202
|
+
# Renders the view as a CSV file.
|
|
203
|
+
#
|
|
204
|
+
# Set the +filename+ you would like to provide to the client, or leave it nil to use the action name.
|
|
205
|
+
# Set the +view_name+ you would like to render, or leave it nil to use the action name.
|
|
206
|
+
def render_csv(filename = nil, view_name = nil)
|
|
207
|
+
|
|
208
|
+
filename ||= params[:action]
|
|
209
|
+
view_name ||= params[:action]
|
|
210
|
+
filename.downcase!
|
|
211
|
+
filename += '.csv' unless filename[-4..-1] == '.csv'
|
|
212
|
+
|
|
213
|
+
headers['Content-Type'] = 'text/csv'
|
|
214
|
+
headers['Content-Disposition'] = "attachment; filename=\"#{filename}\""
|
|
215
|
+
|
|
216
|
+
render view_name, layout: false
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
##
|
|
220
|
+
# A redirects to a previously stored location or to the default location.
|
|
221
|
+
#
|
|
222
|
+
# Usually this will be used to return to an action after a user logs in.
|
|
223
|
+
def redirect_back_or(default)
|
|
224
|
+
redirect_to session[:forwarding_url] || default
|
|
225
|
+
session.delete :forwarding_url
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
##
|
|
229
|
+
# Stores the current URL to be used with #redirect_back_or.
|
|
230
|
+
def store_location
|
|
231
|
+
session[:forwarding_url] = request.url if request.get?
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
protected
|
|
238
|
+
|
|
239
|
+
##
|
|
240
|
+
# This method maps the requested action into the actual action performed.
|
|
241
|
+
#
|
|
242
|
+
# By default, the requested action is returned. If for some reason you want to use a different
|
|
243
|
+
# action in your API, override this method in your controller and map the actions as appropriate.
|
|
244
|
+
#
|
|
245
|
+
# The actions you can expect to translate are 'index', 'new', 'show', and 'edit' for GET requests, and
|
|
246
|
+
# 'create', 'update', and 'destroy' for POST requests. They will be string values or nil, they will not be
|
|
247
|
+
# symbols.
|
|
248
|
+
#
|
|
249
|
+
# The default behavior causes the API to "fall through" to your standard controller methods.
|
|
250
|
+
#
|
|
251
|
+
# The API is accessed by either a POST or a GET request that specifies an `action` parameter. The action
|
|
252
|
+
# gets translated to the acceptable actions listed above and then run through this method for translation.
|
|
253
|
+
#
|
|
254
|
+
def map_api_action(requested_action) #:doc:
|
|
255
|
+
requested_action
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
##
|
|
260
|
+
# Authorizes access for the action.
|
|
261
|
+
#
|
|
262
|
+
# * With no arguments, this will validate that a user is currently logged in, but does not check their permission.
|
|
263
|
+
# * With an argument of true, this will validate that the user currently logged in is an administrator.
|
|
264
|
+
# * With one or more strings, this will validate that the user currently logged in has at least one or more
|
|
265
|
+
# of the named permissions.
|
|
266
|
+
#
|
|
267
|
+
# authorize!
|
|
268
|
+
# authorize! true
|
|
269
|
+
# authorize! "Safety Manager", "HR Manager"
|
|
270
|
+
#
|
|
271
|
+
# If no user is logged in, then the user will be redirected to the login page and the method will return false.
|
|
272
|
+
# If a user is logged in, but is not authorized, then the user will be redirected to the home page and the method
|
|
273
|
+
# will return false.
|
|
274
|
+
# If the user is authorized, the method will return true.
|
|
275
|
+
def authorize!(*accepted_groups) #:doc:
|
|
276
|
+
begin
|
|
277
|
+
|
|
278
|
+
# an authenticated user must exist.
|
|
279
|
+
unless logged_in?
|
|
280
|
+
store_location
|
|
281
|
+
|
|
282
|
+
raise_not_logged_in "You need to login to access '#{request.fullpath}'.",
|
|
283
|
+
'nobody is logged in'
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
if system_admin?
|
|
287
|
+
log_authorize_success 'user is system admin'
|
|
288
|
+
else
|
|
289
|
+
# clean up the group list.
|
|
290
|
+
accepted_groups ||= []
|
|
291
|
+
accepted_groups.flatten!
|
|
292
|
+
accepted_groups.delete false
|
|
293
|
+
accepted_groups.delete ''
|
|
294
|
+
|
|
295
|
+
if accepted_groups.include?(true)
|
|
296
|
+
# group_list contains "true" so only a system admin may continue.
|
|
297
|
+
raise_authorize_failure "Your are not authorized to access '#{request.fullpath}'.",
|
|
298
|
+
'requires system administrator'
|
|
299
|
+
|
|
300
|
+
elsif accepted_groups.blank?
|
|
301
|
+
# group_list is empty or contained nothing but empty strings and boolean false.
|
|
302
|
+
# everyone can continue.
|
|
303
|
+
log_authorize_success 'only requires authenticated user'
|
|
304
|
+
|
|
305
|
+
else
|
|
306
|
+
# the group list contains one or more authorized groups.
|
|
307
|
+
# we want them to all be uppercase strings.
|
|
308
|
+
accepted_groups = accepted_groups.map{|v| v.to_s.upcase}.sort
|
|
309
|
+
result = current_user.has_any_group?(*accepted_groups)
|
|
310
|
+
unless result
|
|
311
|
+
raise_authorize_failure "You are not authorized to access '#{request.fullpath}'.",
|
|
312
|
+
"requires one of: #{accepted_groups.inspect}"
|
|
313
|
+
end
|
|
314
|
+
log_authorize_success "user has #{result.inspect}"
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
rescue ::Incline::NotAuthorized => err
|
|
319
|
+
|
|
320
|
+
flash[:danger] = err.message
|
|
321
|
+
redirect_to root_url and return false
|
|
322
|
+
end
|
|
323
|
+
true
|
|
324
|
+
|
|
325
|
+
end
|
|
326
|
+
|
|
327
|
+
##
|
|
328
|
+
# Is the current request for JSON data?
|
|
329
|
+
#
|
|
330
|
+
# Redirects are generally bad when JSON data is requested.
|
|
331
|
+
# For instance a `create` request in JSON format should return data, not redirect to `show`.
|
|
332
|
+
def json_request? #:doc:
|
|
333
|
+
request.format.to_s.downcase == 'json'
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
##
|
|
337
|
+
# Is the current request an inline request?
|
|
338
|
+
#
|
|
339
|
+
# JSON requests are always considered inline, otherwise we check to see if the "inline" parameter is set to a true value.
|
|
340
|
+
#
|
|
341
|
+
# Primarily this would be used to strip the layour from rendered content.
|
|
342
|
+
def inline_request?
|
|
343
|
+
json_request? || params[:inline].to_bool
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
##
|
|
347
|
+
# Determines if the current request can be allowed via HTTP (non-SSL).
|
|
348
|
+
def allow_http_for_request? #:doc:
|
|
349
|
+
self.class.setting_for_action self.class.allow_non_ssl, params[:action]
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
##
|
|
353
|
+
# Determines if the current request can be allowed with an anonymous user.
|
|
354
|
+
#
|
|
355
|
+
# Overridden by require_admin_for_request?
|
|
356
|
+
# Implied by require_anon_for_request?
|
|
357
|
+
def allow_anon_for_request? #:doc:
|
|
358
|
+
self.class.allow_anon_for? params[:action]
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
##
|
|
362
|
+
# Determines if the current request requires a system administrator.
|
|
363
|
+
#
|
|
364
|
+
# Overrides all other access requirements.
|
|
365
|
+
def require_admin_for_request? #:doc:
|
|
366
|
+
self.class.require_admin_for? params[:action]
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
##
|
|
370
|
+
# Determines if the current request requires an anonymous user.
|
|
371
|
+
#
|
|
372
|
+
# Overridden by require_admin_for_request?
|
|
373
|
+
# Implies allow_anon_for_request?
|
|
374
|
+
def require_anon_for_request? #:doc:
|
|
375
|
+
self.class.require_anon_for? params[:action]
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
private
|
|
380
|
+
|
|
381
|
+
##
|
|
382
|
+
# Validates that the current user is authorized for the current request.
|
|
383
|
+
#
|
|
384
|
+
# This method is called for every action except the :api action.
|
|
385
|
+
# For the :api action, this method will not be called until the actual requested action is performed.
|
|
386
|
+
#
|
|
387
|
+
# One of four scenarios are possible:
|
|
388
|
+
# 1. If the +require_admin+ method applies to the current action, then a system administrator must be logged in.
|
|
389
|
+
# 1. If a nobody is logged in, then the user will be redirected to the login url.
|
|
390
|
+
# 2. If a system administrator is logged in, then access is granted.
|
|
391
|
+
# 3. Non-system administrators will be redirected to the root url.
|
|
392
|
+
# 2. If the +require_anon+ method applies to the current action, then a user cannot be logged in.
|
|
393
|
+
# 1. If a user is logged in, a warning message is set and the user is redirected to their account.
|
|
394
|
+
# 2. If no user is logged in, then access is granted.
|
|
395
|
+
# 3. If the +allow_anon+ method applies to the current action, then access is granted.
|
|
396
|
+
# 4. The action doesn't require a system administrator, but does require a valid user to be logged in.
|
|
397
|
+
# 1. If nobody is logged in, then the user will be redirected to the login url.
|
|
398
|
+
# 2. If a system administrator is logged in, then access is granted.
|
|
399
|
+
# 3. If the action doesn't have any required permissions, then access is granted to any logged in user.
|
|
400
|
+
# 4. If the action has required permissions and the logged in user shares at least one, then access is granted.
|
|
401
|
+
# 5. Users without at least one required permission are redirected to the root url.
|
|
402
|
+
#
|
|
403
|
+
# Two of the scenarios are configured at design time. If you use +require_admin+ or +allow_anon+,
|
|
404
|
+
# they cannot be changed at runtime. The idea is that anything that allows anonymous access will always allow
|
|
405
|
+
# anonymous access during runtime and anything that requires admin access will always require admin access during
|
|
406
|
+
# runtime.
|
|
407
|
+
#
|
|
408
|
+
# The third scenario is what would be used by most actions. Using the +admin+ controller, which requires admin
|
|
409
|
+
# access, you can customize the permissions required for each available route. Using the +users+ controller,
|
|
410
|
+
# admins can assign permissions to other users.
|
|
411
|
+
#
|
|
412
|
+
def valid_user? #:doc:
|
|
413
|
+
if require_admin_for_request?
|
|
414
|
+
authorize! true
|
|
415
|
+
elsif require_anon_for_request?
|
|
416
|
+
if logged_in?
|
|
417
|
+
flash[:warning] = 'The specified action cannot be performed while logged in.'
|
|
418
|
+
redirect_to current_user
|
|
419
|
+
end
|
|
420
|
+
elsif allow_anon_for_request?
|
|
421
|
+
true
|
|
422
|
+
else
|
|
423
|
+
action = Incline::ActionSecurity.valid_items[self.class.controller_path, params[:action]]
|
|
424
|
+
if action && action.groups.count > 0
|
|
425
|
+
authorize! action.groups.pluck(:name)
|
|
426
|
+
else
|
|
427
|
+
authorize!
|
|
428
|
+
end
|
|
429
|
+
end
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
def process_api_action(raise_on_invalid_action = true, default_get_action = 'index')
|
|
434
|
+
api_action =
|
|
435
|
+
map_api_action(
|
|
436
|
+
if request.post?
|
|
437
|
+
# A post request can create, update, or destroy.
|
|
438
|
+
# In addition we allow index to post since DataTables can send quite a bit of data with server-side
|
|
439
|
+
# processing.
|
|
440
|
+
# The post action can be provided as a query parameter or a form parameter with the form parameter
|
|
441
|
+
# taking priority.
|
|
442
|
+
{
|
|
443
|
+
nil => 'index',
|
|
444
|
+
'list' => 'index',
|
|
445
|
+
'index' => 'index',
|
|
446
|
+
'new' => 'create',
|
|
447
|
+
'create' => 'create',
|
|
448
|
+
'edit' => 'update',
|
|
449
|
+
'update' => 'update',
|
|
450
|
+
'remove' => 'destroy',
|
|
451
|
+
'destroy' => 'destroy'
|
|
452
|
+
}[request.request_parameters.delete('action') || request.query_parameters.delete('action')]
|
|
453
|
+
elsif request.get?
|
|
454
|
+
# For the most part, these shouldn't be used except for maybe index and show.
|
|
455
|
+
# The new and edit actions could be used if for some reason you need to supply data to the ajax form
|
|
456
|
+
# calling these actions, e.g. - a list of locations.
|
|
457
|
+
# Datatables Editor does not use any of them.
|
|
458
|
+
# Datatables will simple be requesting the index action in JSON format.
|
|
459
|
+
# To remain consistent though, you can use '?action=list' to perform the same feat.
|
|
460
|
+
{
|
|
461
|
+
'list' => 'index',
|
|
462
|
+
'index' => 'index',
|
|
463
|
+
'new' => 'new',
|
|
464
|
+
'show' => 'show',
|
|
465
|
+
'edit' => 'edit'
|
|
466
|
+
}[request.query_parameters.delete('action')] || default_get_action
|
|
467
|
+
else
|
|
468
|
+
nil
|
|
469
|
+
end
|
|
470
|
+
)
|
|
471
|
+
|
|
472
|
+
if api_action
|
|
473
|
+
# Datatables Editor sends the 'data' in the 'data' parameter.
|
|
474
|
+
# We simple want to move that up a level so `params[:data][:user][:name]` becomes `params[:user][:name]`.
|
|
475
|
+
data = request.params.delete('data')
|
|
476
|
+
unless data.blank?
|
|
477
|
+
# get the first entry in the hash.
|
|
478
|
+
id, item = data.first
|
|
479
|
+
|
|
480
|
+
# if the id is in AAAAA_NNN format, then we can extract the ID from it.
|
|
481
|
+
if id.include?('_')
|
|
482
|
+
params[:id] = id.split('_').last.to_i
|
|
483
|
+
end
|
|
484
|
+
|
|
485
|
+
# merge the item data into the params array.
|
|
486
|
+
params.merge! item
|
|
487
|
+
end
|
|
488
|
+
|
|
489
|
+
# since we are processing for an API request, we should return JSON.
|
|
490
|
+
request.format = :json
|
|
491
|
+
|
|
492
|
+
# finally, we'll start over on processing the stack.
|
|
493
|
+
# This should ensure the appropriate `before_action` filters are called for the new action.
|
|
494
|
+
process api_action
|
|
495
|
+
else
|
|
496
|
+
# raise an error.
|
|
497
|
+
raise Incline::InvalidApiCall, 'Invalid API Action' if raise_on_invalid_action
|
|
498
|
+
nil
|
|
499
|
+
end
|
|
500
|
+
end
|
|
501
|
+
|
|
502
|
+
def raise_authorize_failure(message, log_message = nil)
|
|
503
|
+
log_authorize_failure message, log_message
|
|
504
|
+
raise Incline::NotAuthorized.new(message)
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
def raise_not_logged_in(message, log_message = nil)
|
|
508
|
+
log_authorize_failure message, log_message
|
|
509
|
+
raise Incline::NotLoggedIn.new(message)
|
|
510
|
+
end
|
|
511
|
+
|
|
512
|
+
def log_authorize_failure(message, log_message = nil)
|
|
513
|
+
log_message ||= message
|
|
514
|
+
Incline::Log::info "AUTH(FAILURE): #{request.fullpath}, #{current_user}, #{log_message}"
|
|
515
|
+
end
|
|
516
|
+
|
|
517
|
+
def log_authorize_success(message)
|
|
518
|
+
Incline::Log::info "AUTH(SUCCESS): #{request.fullpath}, #{current_user}, #{message}"
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
end
|
|
522
|
+
|
|
523
|
+
end
|
|
524
|
+
|
|
525
|
+
ActionController::Base.include Incline::Extensions::ActionControllerBase
|
|
526
|
+
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
require 'action_mailer'
|
|
2
|
+
|
|
3
|
+
module Incline::Extensions
|
|
4
|
+
|
|
5
|
+
##
|
|
6
|
+
# Adds the default_hostname, default_sender, and default_recipient methods to the ApplicationMailer::Base class.
|
|
7
|
+
module ActionMailerBase
|
|
8
|
+
|
|
9
|
+
##
|
|
10
|
+
# Adds the extra class methods to the ApplicationMailer::Base class.
|
|
11
|
+
module ClassMethods
|
|
12
|
+
##
|
|
13
|
+
# Gets the default hostname for messages.
|
|
14
|
+
def default_hostname
|
|
15
|
+
@default_hostname ||= Incline::email_config[:default_hostname]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
##
|
|
19
|
+
# Gets the default sender for messages.
|
|
20
|
+
def default_sender
|
|
21
|
+
@default_sender ||= Incline::email_config[:sender]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
##
|
|
25
|
+
# Gets the default recipient for messages.
|
|
26
|
+
def default_recipient
|
|
27
|
+
@default_recipient ||= Incline::email_config[:default_recipient]
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
##
|
|
32
|
+
# Sets the default from and to address according to the configuration.
|
|
33
|
+
def self.included(base)
|
|
34
|
+
base.extend ClassMethods
|
|
35
|
+
|
|
36
|
+
class << self
|
|
37
|
+
|
|
38
|
+
private
|
|
39
|
+
|
|
40
|
+
if method_defined?(:inherited)
|
|
41
|
+
alias_method :incline_original_inherited, :inherited
|
|
42
|
+
else
|
|
43
|
+
def incline_original_inherited(subclass)
|
|
44
|
+
# Do nothing.
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def inherited(subclass)
|
|
49
|
+
incline_original_inherited subclass
|
|
50
|
+
|
|
51
|
+
default(
|
|
52
|
+
{
|
|
53
|
+
from: default_sender,
|
|
54
|
+
to: default_recipient
|
|
55
|
+
}
|
|
56
|
+
)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
ActionMailer::Base.include Incline::Extensions::ActionMailerBase
|