barkest_core 1.5.3.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/.gitignore +13 -0
- data/Gemfile +22 -0
- data/Gemfile.lock +254 -0
- data/MIT-LICENSE +20 -0
- data/README.md +364 -0
- data/Rakefile +37 -0
- data/app/assets/fonts/barkest_core/ArchivoNarrow-Bold.ttf +0 -0
- data/app/assets/fonts/barkest_core/ArchivoNarrow-BoldItalic.ttf +0 -0
- data/app/assets/fonts/barkest_core/ArchivoNarrow-Italic.ttf +0 -0
- data/app/assets/fonts/barkest_core/ArchivoNarrow-Regular.ttf +0 -0
- data/app/assets/images/barkest_core/.keep +0 -0
- data/app/assets/images/barkest_core/barcode-B.svg +181 -0
- data/app/assets/javascripts/barkest_core/.keep +0 -0
- data/app/assets/javascripts/barkest_core/application.js +22 -0
- data/app/assets/javascripts/barkest_core/bootstrap-datepicker.js +1800 -0
- data/app/assets/javascripts/barkest_core/field_init.js +7 -0
- data/app/assets/javascripts/barkest_core/jquery.doubleScroll.js +112 -0
- data/app/assets/javascripts/barkest_core/masked_edit.js +25 -0
- data/app/assets/javascripts/barkest_core/system_status.js.erb +201 -0
- data/app/assets/stylesheets/barkest_core/.keep +0 -0
- data/app/assets/stylesheets/barkest_core/application.css +17 -0
- data/app/assets/stylesheets/barkest_core/custom.css.scss +264 -0
- data/app/assets/stylesheets/barkest_core/datepicker3.css +790 -0
- data/app/controllers/.keep +0 -0
- data/app/controllers/access_groups_controller.rb +74 -0
- data/app/controllers/account_activations_controller.rb +29 -0
- data/app/controllers/application_controller.rb +5 -0
- data/app/controllers/barkest_core/application_controller_base.rb +113 -0
- data/app/controllers/barkest_core/engine_controller_base.rb +15 -0
- data/app/controllers/barkest_core/testsub_controller.rb +21 -0
- data/app/controllers/contact_controller.rb +32 -0
- data/app/controllers/log_view_controller.rb +31 -0
- data/app/controllers/password_resets_controller.rb +126 -0
- data/app/controllers/sessions_controller.rb +64 -0
- data/app/controllers/status_controller.rb +150 -0
- data/app/controllers/system_config_controller.rb +238 -0
- data/app/controllers/system_update_controller.rb +164 -0
- data/app/controllers/test_access_controller.rb +44 -0
- data/app/controllers/test_report_controller.rb +75 -0
- data/app/controllers/users_controller.rb +218 -0
- data/app/helpers/.keep +0 -0
- data/app/helpers/barkest_core/application_helper.rb +134 -0
- data/app/helpers/barkest_core/form_helper.rb +469 -0
- data/app/helpers/barkest_core/html_helper.rb +70 -0
- data/app/helpers/barkest_core/misc_helper.rb +68 -0
- data/app/helpers/barkest_core/pdf_helper.rb +180 -0
- data/app/helpers/barkest_core/recaptcha_helper.rb +115 -0
- data/app/helpers/barkest_core/sessions_helper.rb +94 -0
- data/app/helpers/barkest_core/status_helper.rb +118 -0
- data/app/helpers/barkest_core/users_helper.rb +32 -0
- data/app/mailers/.keep +0 -0
- data/app/mailers/application_mailer.rb +5 -0
- data/app/mailers/barkest_core/application_mailer_base.rb +30 -0
- data/app/mailers/barkest_core/contact_form.rb +20 -0
- data/app/mailers/barkest_core/user_mailer.rb +44 -0
- data/app/models/.keep +0 -0
- data/app/models/access_group.rb +121 -0
- data/app/models/access_group_group_member.rb +13 -0
- data/app/models/access_group_user_member.rb +11 -0
- data/app/models/barkest_core/auth_config.rb +95 -0
- data/app/models/barkest_core/authorize_failure.rb +7 -0
- data/app/models/barkest_core/contact_message.rb +37 -0
- data/app/models/barkest_core/database_config.rb +223 -0
- data/app/models/barkest_core/db_table.rb +21 -0
- data/app/models/barkest_core/email_config.rb +132 -0
- data/app/models/barkest_core/global_status.rb +267 -0
- data/app/models/barkest_core/log_entry.rb +101 -0
- data/app/models/barkest_core/log_view_options.rb +51 -0
- data/app/models/barkest_core/ms_sql_db_definition.rb +441 -0
- data/app/models/barkest_core/ms_sql_definition.rb +221 -0
- data/app/models/barkest_core/ms_sql_function.rb +423 -0
- data/app/models/barkest_core/not_logged_in.rb +7 -0
- data/app/models/barkest_core/pdf_table_builder.rb +407 -0
- data/app/models/barkest_core/self_update_config.rb +37 -0
- data/app/models/barkest_core/user_alert.rb +29 -0
- data/app/models/barkest_core/user_alert_generators.rb +58 -0
- data/app/models/barkest_core/user_manager.rb +404 -0
- data/app/models/barkest_core/work_path.rb +74 -0
- data/app/models/disable_user.rb +18 -0
- data/app/models/ldap_access_group.rb +15 -0
- data/app/models/system_config.rb +99 -0
- data/app/models/user.rb +405 -0
- data/app/models/user_login_history.rb +11 -0
- data/app/views/.keep +0 -0
- data/app/views/access_groups/_form.html.erb +19 -0
- data/app/views/access_groups/edit.html.erb +2 -0
- data/app/views/access_groups/index.html.erb +32 -0
- data/app/views/access_groups/new.html.erb +2 -0
- data/app/views/access_groups/show.html.erb +4 -0
- data/app/views/barkest_core/contact_form/contact.html.erb +16 -0
- data/app/views/barkest_core/contact_form/contact.text.erb +13 -0
- data/app/views/barkest_core/testsub/_links.html.erb +5 -0
- data/app/views/barkest_core/testsub/page1.html.erb +3 -0
- data/app/views/barkest_core/testsub/page2.html.erb +2 -0
- data/app/views/barkest_core/testsub/page3.html.erb +2 -0
- data/app/views/barkest_core/user_mailer/account_activation.html.erb +7 -0
- data/app/views/barkest_core/user_mailer/account_activation.text.erb +6 -0
- data/app/views/barkest_core/user_mailer/invalid_password_reset.html.erb +3 -0
- data/app/views/barkest_core/user_mailer/invalid_password_reset.text.erb +5 -0
- data/app/views/barkest_core/user_mailer/password_reset.html.erb +8 -0
- data/app/views/barkest_core/user_mailer/password_reset.text.erb +7 -0
- data/app/views/contact/index.html.erb +24 -0
- data/app/views/layouts/_footer_copyright.html.erb +1 -0
- data/app/views/layouts/_menu_admin.html.erb +5 -0
- data/app/views/layouts/_menu_anon.html.erb +0 -0
- data/app/views/layouts/_menu_auth.html.erb +3 -0
- data/app/views/layouts/_menu_footer.html.erb +1 -0
- data/app/views/layouts/_nav_logo.html.erb +1 -0
- data/app/views/layouts/application.html.erb +2 -0
- data/app/views/layouts/barkest_core/_application.html.erb +24 -0
- data/app/views/layouts/barkest_core/_footer.html.erb +18 -0
- data/app/views/layouts/barkest_core/_header.html.erb +38 -0
- data/app/views/layouts/barkest_core/_html_mailer.html.erb +11 -0
- data/app/views/layouts/barkest_core/_menu_account.html.erb +14 -0
- data/app/views/layouts/barkest_core/_menu_sample.html.erb +1 -0
- data/app/views/layouts/barkest_core/_messages.html.erb +4 -0
- data/app/views/layouts/barkest_core/_shim.html.erb +4 -0
- data/app/views/layouts/barkest_core/_subheader.html.erb +1 -0
- data/app/views/layouts/barkest_core/_text_mailer.text.erb +4 -0
- data/app/views/layouts/mailer.html.erb +1 -0
- data/app/views/layouts/mailer.text.erb +1 -0
- data/app/views/log_view/index.html.erb +100 -0
- data/app/views/password_resets/edit.html.erb +20 -0
- data/app/views/password_resets/new.html.erb +14 -0
- data/app/views/sessions/new.html.erb +27 -0
- data/app/views/shared/_error_messages.html.erb +29 -0
- data/app/views/shared/_generic_user_alert.html.erb +4 -0
- data/app/views/status/current.html.erb +34 -0
- data/app/views/status/test.html.erb +50 -0
- data/app/views/system_config/index.html.erb +25 -0
- data/app/views/system_config/show_auth.html.erb +28 -0
- data/app/views/system_config/show_database.html.erb +36 -0
- data/app/views/system_config/show_email.html.erb +21 -0
- data/app/views/system_config/show_self_update.html.erb +13 -0
- data/app/views/system_update/index.html.erb +31 -0
- data/app/views/system_update/new.html.erb +2 -0
- data/app/views/test_access/allow_anon.html.erb +2 -0
- data/app/views/test_access/require_admin.html.erb +2 -0
- data/app/views/test_access/require_group_x.html.erb +2 -0
- data/app/views/test_access/require_user.html.erb +2 -0
- data/app/views/test_report/index.csv.csvrb +23 -0
- data/app/views/test_report/index.html.erb +6 -0
- data/app/views/test_report/index.pdf.prawn +50 -0
- data/app/views/test_report/index.xlsx.axlsx +28 -0
- data/app/views/users/_user.html.erb +57 -0
- data/app/views/users/_user_details.html.erb +15 -0
- data/app/views/users/_user_details_for_list.html.erb +1 -0
- data/app/views/users/_user_form.html.erb +13 -0
- data/app/views/users/disable_confirm.html.erb +19 -0
- data/app/views/users/edit.html.erb +15 -0
- data/app/views/users/index.html.erb +9 -0
- data/app/views/users/new.html.erb +10 -0
- data/app/views/users/show.html.erb +46 -0
- data/bin/rails +12 -0
- data/config/routes.rb +3 -0
- data/db/migrate/20160617172539_create_access_groups.rb +10 -0
- data/db/migrate/20160617172725_create_users.rb +26 -0
- data/db/migrate/20160617172833_create_user_login_histories.rb +12 -0
- data/db/migrate/20160622151720_create_access_group_user_members.rb +9 -0
- data/db/migrate/20160622151925_create_access_group_group_members.rb +9 -0
- data/db/migrate/20160701005706_create_ldap_access_groups.rb +11 -0
- data/db/migrate/20161108155029_create_system_configs.rb +11 -0
- data/db/seeds/barkest_core_01_create_users.rb +42 -0
- data/db/seeds.rb +53 -0
- data/lib/barkest_core/concerns/association_with_defaults.rb +55 -0
- data/lib/barkest_core/concerns/boolean_parser.rb +88 -0
- data/lib/barkest_core/concerns/date_parser.rb +181 -0
- data/lib/barkest_core/concerns/email_tester.rb +55 -0
- data/lib/barkest_core/concerns/encrypted_fields.rb +156 -0
- data/lib/barkest_core/concerns/named_model.rb +73 -0
- data/lib/barkest_core/concerns/number_parser.rb +145 -0
- data/lib/barkest_core/concerns/utc_conversion.rb +60 -0
- data/lib/barkest_core/engine.rb +105 -0
- data/lib/barkest_core/extensions/active_record_extensions.rb +120 -0
- data/lib/barkest_core/extensions/application_configuration_extensions.rb +38 -0
- data/lib/barkest_core/extensions/application_extensions.rb +50 -0
- data/lib/barkest_core/extensions/axlsx_extenstions.rb +157 -0
- data/lib/barkest_core/extensions/fixture_set_extensions.rb +107 -0
- data/lib/barkest_core/extensions/generator_extensions.rb +271 -0
- data/lib/barkest_core/extensions/main_app_extensions.rb +35 -0
- data/lib/barkest_core/extensions/prawn_document_extensions.rb +367 -0
- data/lib/barkest_core/extensions/prawn_table_extensions.rb +131 -0
- data/lib/barkest_core/extensions/router_extensions.rb +106 -0
- data/lib/barkest_core/extensions/simple_formatter_extensions.rb +66 -0
- data/lib/barkest_core/extensions/test_case_extensions.rb +348 -0
- data/lib/barkest_core/extensions/time_extensions.rb +164 -0
- data/lib/barkest_core/handlers/csv_handler.rb +30 -0
- data/lib/barkest_core/version.rb +3 -0
- data/lib/barkest_core.rb +324 -0
- data/lib/generators/barkest/install_generator.rb +102 -0
- data/lib/generators/barkest_core/actions/01_patch_application_controller.rb +55 -0
- data/lib/generators/barkest_core/actions/02_patch_application_mailer.rb +56 -0
- data/lib/generators/barkest_core/actions/03_patch_assets.rb +62 -0
- data/lib/generators/barkest_core/actions/04_patch_layouts.rb +36 -0
- data/lib/generators/barkest_core/actions/05_patch_routes.rb +93 -0
- data/lib/generators/barkest_core/actions/06_patch_seeds.rb +60 -0
- data/lib/generators/barkest_core/actions/07_copy_migrations.rb +51 -0
- data/lib/generators/barkest_core/actions/08_configure_database.rb +52 -0
- data/lib/generators/barkest_core/actions/09_configure_secrets.rb +29 -0
- data/lib/generators/barkest_core/actions/99_patch_gitignore.rb +57 -0
- data/lib/generators/barkest_core/install_generator.rb +17 -0
- data/test/barkest_core_test.rb +83 -0
- data/test/controllers/access_groups_controller_test.rb +53 -0
- data/test/controllers/contact_controller_test.rb +10 -0
- data/test/controllers/sessions_controller_test.rb +10 -0
- data/test/controllers/users_controller_test.rb +10 -0
- data/test/dummy/.gitignore +10 -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 +14 -0
- data/test/dummy/app/assets/stylesheets/application.css +16 -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/mailers/application_mailer.rb +3 -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/mailer.html.erb +1 -0
- data/test/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/test/dummy/app/views/system_config/show_fake.html.erb +3 -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 +27 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +47 -0
- data/test/dummy/config/environments/production.rb +79 -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/db_updater_ext.rb +33 -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/sys_config_ext.rb +12 -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 +60 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/db/schema.rb +95 -0
- data/test/dummy/db/seeds/barkest_core_01_create_users.rb +42 -0
- data/test/dummy/db/seeds.rb +51 -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/dummy/sql/my_test_view.sql +3 -0
- data/test/fixtures/access_groups.yml +21 -0
- data/test/fixtures/users.yml +71 -0
- data/test/helpers/barkest_core/sessions_helper_test.rb +22 -0
- data/test/integration/access_group_mgmt_test.rb +33 -0
- data/test/integration/access_test.rb +24 -0
- data/test/integration/account_activations_access_test.rb +12 -0
- data/test/integration/contact_test.rb +98 -0
- data/test/integration/extra_partial_test.rb +41 -0
- data/test/integration/log_view_access_test.rb +12 -0
- data/test/integration/password_resets_test.rb +101 -0
- data/test/integration/reports_test.rb +53 -0
- data/test/integration/status_access_test.rb +27 -0
- data/test/integration/system_config_access_test.rb +24 -0
- data/test/integration/system_update_access_test.rb +19 -0
- data/test/integration/users_access_test.rb +34 -0
- data/test/integration/users_edit_test.rb +178 -0
- data/test/integration/users_index_test.rb +62 -0
- data/test/integration/users_login_test.rb +67 -0
- data/test/integration/users_signup_test.rb +54 -0
- data/test/mailers/.keep +0 -0
- data/test/mailers/barkest_core/contact_form_test.rb +28 -0
- data/test/mailers/barkest_core/user_mailer_test.rb +43 -0
- data/test/mailers/previews/barkest_core/contact_form_preview.rb +17 -0
- data/test/mailers/previews/barkest_core/user_mailer_preview.rb +26 -0
- data/test/models/access_group_group_member_test.rb +28 -0
- data/test/models/access_group_test.rb +114 -0
- data/test/models/access_group_user_member_test.rb +28 -0
- data/test/models/barkest_core/auth_config_test.rb +57 -0
- data/test/models/barkest_core/bool_parser_test.rb +28 -0
- data/test/models/barkest_core/contact_message_test.rb +61 -0
- data/test/models/barkest_core/database_config_test.rb +33 -0
- data/test/models/barkest_core/date_parser_test.rb +110 -0
- data/test/models/barkest_core/email_config_test.rb +57 -0
- data/test/models/barkest_core/global_status_test.rb +50 -0
- data/test/models/barkest_core/ms_sql_db_updater_test.rb +115 -0
- data/test/models/barkest_core/ms_sql_definition_test.rb +102 -0
- data/test/models/barkest_core/ms_sql_function_test.rb +131 -0
- data/test/models/barkest_core/number_parser_test.rb +29 -0
- data/test/models/barkest_core/self_update_config_test.rb +29 -0
- data/test/models/barkest_core/user_alert_test.rb +19 -0
- data/test/models/barkest_core/user_manager_test.rb +34 -0
- data/test/models/barkest_core/work_path_test.rb +26 -0
- data/test/models/disable_user_test.rb +27 -0
- data/test/models/generic_time_test.rb +66 -0
- data/test/models/ldap_access_group_test.rb +31 -0
- data/test/models/pdf_table_builder_test.rb +6 -0
- data/test/models/system_config_test.rb +78 -0
- data/test/models/user_login_history_test.rb +37 -0
- data/test/models/user_test.rb +130 -0
- data/test/test_helper.rb +63 -0
- metadata +798 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
module BarkestCore
|
|
2
|
+
|
|
3
|
+
##
|
|
4
|
+
# This module allows you to define defaults for a model's associations.
|
|
5
|
+
#
|
|
6
|
+
# While models can be setup with static defaults, this allows you to
|
|
7
|
+
# provide dynamic defaults. You must define the +association_defaults+ method
|
|
8
|
+
# within the association block for it to work though. This method should process
|
|
9
|
+
# the attributes in whatever way it needs. In the example below, we would actually
|
|
10
|
+
# want to look for +org+ and +access+ attributes before overriding the +org_id+ and
|
|
11
|
+
# +access_id+ attributes.
|
|
12
|
+
#
|
|
13
|
+
# This method will override the +new+, +build+, +create+, and +create!+ methods
|
|
14
|
+
# of the association to ensure the dynamic defaults are processed properly.
|
|
15
|
+
#
|
|
16
|
+
# class User
|
|
17
|
+
# ...
|
|
18
|
+
# has_many :accesses, ->{ extending BarkestCore::AssociationWithDefaults } do
|
|
19
|
+
# def association_defaults(attributes = {})
|
|
20
|
+
# {
|
|
21
|
+
# org_id: proxy_association.owner.current_organization.id,
|
|
22
|
+
# access_id: Access.default.id
|
|
23
|
+
# }.merge(attributes || {})
|
|
24
|
+
# end
|
|
25
|
+
# end
|
|
26
|
+
# ...
|
|
27
|
+
# end
|
|
28
|
+
#
|
|
29
|
+
module AssociationWithDefaults
|
|
30
|
+
# def association_defaults(attributes = {})
|
|
31
|
+
# attributes[:some_value] ||= some_default
|
|
32
|
+
# attributes
|
|
33
|
+
# end
|
|
34
|
+
|
|
35
|
+
def new(attributes = {})
|
|
36
|
+
super association_defaults(attributes)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def build(*args)
|
|
40
|
+
args << {} if args.blank?
|
|
41
|
+
args = args.map { |a| a.is_a?(Hash) ? association_defaults(a) : a }
|
|
42
|
+
super(*args)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def create(attributes = {})
|
|
46
|
+
super association_defaults(attributes)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def create!(attributes = {})
|
|
50
|
+
super association_defaults(attributes)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
module BarkestCore
|
|
2
|
+
##
|
|
3
|
+
# This module will add boolean parsing functions to a class.
|
|
4
|
+
#
|
|
5
|
+
module BooleanParser
|
|
6
|
+
|
|
7
|
+
##
|
|
8
|
+
# Parses for a 3-way boolean.
|
|
9
|
+
#
|
|
10
|
+
# If the value is nil, then nil is returned.
|
|
11
|
+
# If the value is 'true', 'yes', 'on', '1', 't', or 'y' then true is returned.
|
|
12
|
+
# Otherwise false is returned.
|
|
13
|
+
#
|
|
14
|
+
def self.parse_for_boolean_column(value)
|
|
15
|
+
return nil if value.to_s.blank?
|
|
16
|
+
value = value.to_s.downcase
|
|
17
|
+
%w(true yes on 1 -1 t y).include? value
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
##
|
|
21
|
+
# Parses the value for a 3-way SQL filter.
|
|
22
|
+
#
|
|
23
|
+
# If the value is nil, then 'NULL' is returned.
|
|
24
|
+
# If the value parses to true, then '1' is returned.
|
|
25
|
+
# Otherwise '0' is returned.
|
|
26
|
+
#
|
|
27
|
+
def self.parse_for_boolean_filter(value)
|
|
28
|
+
value = parse_for_boolean_column(value)
|
|
29
|
+
return 'NULL' if value.nil?
|
|
30
|
+
value ? '1' : '0'
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# :nodoc:
|
|
34
|
+
def self.included(base)
|
|
35
|
+
base.class_eval do
|
|
36
|
+
|
|
37
|
+
##
|
|
38
|
+
# Parses for a 3-way boolean.
|
|
39
|
+
#
|
|
40
|
+
# If the value is nil, then nil is returned.
|
|
41
|
+
# If the value is 'true', 'yes', 'on', '1', 't', or 'y' then true is returned.
|
|
42
|
+
# Otherwise false is returned.
|
|
43
|
+
#
|
|
44
|
+
def self.parse_for_boolean_column(value)
|
|
45
|
+
BarkestCore::BooleanParser.parse_for_boolean_column value
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
##
|
|
49
|
+
# Parses the value for a 3-way SQL filter.
|
|
50
|
+
#
|
|
51
|
+
# If the value is nil, then 'NULL' is returned.
|
|
52
|
+
# If the value parses to true, then '1' is returned.
|
|
53
|
+
# Otherwise '0' is returned.
|
|
54
|
+
#
|
|
55
|
+
def self.parse_for_boolean_filter(value)
|
|
56
|
+
BarkestCore::BooleanParser.parse_for_boolean_filter value
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
protected
|
|
64
|
+
|
|
65
|
+
##
|
|
66
|
+
# Parses for a 3-way boolean.
|
|
67
|
+
#
|
|
68
|
+
# If the value is nil, then nil is returned.
|
|
69
|
+
# If the value is 'true', 'yes', 'on', '1', 't', or 'y' then true is returned.
|
|
70
|
+
# Otherwise false is returned.
|
|
71
|
+
#
|
|
72
|
+
def parse_for_boolean_column(value)
|
|
73
|
+
BarkestCore::BooleanParser.parse_for_boolean_column value
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
##
|
|
77
|
+
# Parses the value for a 3-way SQL filter.
|
|
78
|
+
#
|
|
79
|
+
# If the value is nil, then 'NULL' is returned.
|
|
80
|
+
# If the value parses to true, then '1' is returned.
|
|
81
|
+
# Otherwise '0' is returned.
|
|
82
|
+
#
|
|
83
|
+
def parse_for_boolean_filter(value)
|
|
84
|
+
BarkestCore::BooleanParser.parse_for_boolean_filter value
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
end
|
|
88
|
+
end
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
module BarkestCore
|
|
2
|
+
##
|
|
3
|
+
# This module will add consistent date parsing functions to a class.
|
|
4
|
+
#
|
|
5
|
+
module DateParser
|
|
6
|
+
|
|
7
|
+
##
|
|
8
|
+
# A regular expression to parse either American format MM/DD/YYYY or ISO format YYYY-MM-DD dates.
|
|
9
|
+
DATE_REGEX = /^(?:(?<M>\d{1,2})\/(?<D>\d{1,2})\/(?<Y>\d{2,4})|(?<Y>\d{2,4})-(?<M>\d{1,2})-(?<D>\d{1,2}))(?:\s.*)?$/
|
|
10
|
+
|
|
11
|
+
##
|
|
12
|
+
# A regular expression to parse either American format MM/DD/YYYY or ISO format YYYY-MM-DD dates, but also allows for a blank value.
|
|
13
|
+
NULLABLE_DATE_REGEX = /^(?:(?:(?<M>\d{1,2})\/(?<D>\d{1,2})\/(?<Y>\d{2,4})|(?<Y>\d{2,4})-(?<M>\d{1,2})-(?<D>\d{1,2}))(?:\s.*)?)?$/
|
|
14
|
+
|
|
15
|
+
##
|
|
16
|
+
# A regular expression to parse either American format MM/DD/YYY HH:MM:SS or ISO format YYYY-MM-DD HH:MM:SS times.
|
|
17
|
+
TIME_REGEX = /^(?:(?:(?<M>\d{1,2})\/(?<D>\d{1,2})\/(?<Y>\d{2,4})|(?<Y>\d{2,4})-(?<M>\d{1,2})-(?<D>\d{1,2}))\s+)?(?:(?<H>\d{1,2})\:(?<N>\d{1,2})(?:\:(?<S>\d{1,2}))?)(?:\s+(?<T>AM|PM).*)?$/i
|
|
18
|
+
|
|
19
|
+
##
|
|
20
|
+
# A regular expression to parse either American format MM/DD/YYY HH:MM:SS or ISO format YYYY-MM-DD HH:MM:SS times, but also allows for a blank value.
|
|
21
|
+
NULLABLE_TIME_REGEX = /^(?:(?:(?:(?<M>\d{1,2})\/(?<D>\d{1,2})\/(?<Y>\d{2,4})|(?<Y>\d{2,4})-(?<M>\d{1,2})-(?<D>\d{1,2}))\s+)?(?:(?<H>\d{1,2})\:(?<N>\d{1,2})(?:\:(?<S>\d{1,2}))?)(?:\s+(?<T>AM|PM).*)?)?$/i
|
|
22
|
+
|
|
23
|
+
##
|
|
24
|
+
# A simple hash that can be used to validate a date entry column.
|
|
25
|
+
#
|
|
26
|
+
# validates :my_date, :format => DATE_FORMAT
|
|
27
|
+
#
|
|
28
|
+
DATE_FORMAT = { with: DATE_REGEX, multiline: true, message: 'must be in MM/DD/YYYY or YYYY-MM-DD format' }
|
|
29
|
+
|
|
30
|
+
##
|
|
31
|
+
# A simple hash that can be used to validate a nullable date entry column.
|
|
32
|
+
#
|
|
33
|
+
# validates :my_date, :format => NULLABLE_DATE_FORMAT
|
|
34
|
+
#
|
|
35
|
+
NULLABLE_DATE_FORMAT = { with: NULLABLE_DATE_REGEX, multiline: true, message: 'must be in MM/DD/YYYY or YYYY-MM-DD format' }
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
private_constant :DATE_REGEX, :TIME_REGEX, :NULLABLE_DATE_REGEX, :NULLABLE_TIME_REGEX
|
|
39
|
+
|
|
40
|
+
##
|
|
41
|
+
# Parses a value for storage in a date/datetime column.
|
|
42
|
+
#
|
|
43
|
+
# Value should be a string in 'M/D/YYYY' or 'YYYY-MM-DD' format but can also be a Date or Time object.
|
|
44
|
+
#
|
|
45
|
+
# Returns a Time object or nil if value is invalid.
|
|
46
|
+
#
|
|
47
|
+
def self.parse_for_date_column(value)
|
|
48
|
+
Time.utc_parse(value).date rescue nil
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
##
|
|
52
|
+
# Parses a value for storage in a datetime column.
|
|
53
|
+
#
|
|
54
|
+
# Value should be a string in 'M/D/YYYY HH:MM:SS' or 'YYYY-MM-DD HH:MM:SS' format, but can also be a Date or Time object.
|
|
55
|
+
#
|
|
56
|
+
# Returns a Time object or nil if value is invalid.
|
|
57
|
+
#
|
|
58
|
+
def self.parse_for_time_column(value)
|
|
59
|
+
Time.utc_parse(value) rescue nil
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
##
|
|
63
|
+
# Parses a value for use in a SQL query.
|
|
64
|
+
#
|
|
65
|
+
# Returns NULL if the parsed date is nil.
|
|
66
|
+
# Otherwise returns the date in 'YYYY-MM-DD' format.
|
|
67
|
+
#
|
|
68
|
+
def self.parse_for_date_filter(value)
|
|
69
|
+
value = parse_for_date_column(value)
|
|
70
|
+
return 'NULL' unless value
|
|
71
|
+
value.strftime('\'%Y-%m-%d\'')
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
##
|
|
75
|
+
# Parses a value for use in a SQL query.
|
|
76
|
+
#
|
|
77
|
+
# Returns NULL if the parsed time is nil.
|
|
78
|
+
# Otherwise returns the time in 'YYYY-MM-DD HH:MM:SS' format.
|
|
79
|
+
#
|
|
80
|
+
def self.parse_for_time_filter(value)
|
|
81
|
+
value = parse_for_time_column(value)
|
|
82
|
+
return 'NULL' unless value
|
|
83
|
+
value.strftime('\'%Y-%m-%d %H:%M:%S\'')
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# :nodoc:
|
|
87
|
+
def self.included(base)
|
|
88
|
+
base.class_eval do
|
|
89
|
+
|
|
90
|
+
##
|
|
91
|
+
# Parses a value for storage in a date/datetime column.
|
|
92
|
+
#
|
|
93
|
+
# Value should be a string in 'M/D/YYYY' or 'YYYY-MM-DD' format but can also be a Date or Time object.
|
|
94
|
+
#
|
|
95
|
+
# Returns a Time object or nil if value is invalid.
|
|
96
|
+
#
|
|
97
|
+
def self.parse_for_date_column(value)
|
|
98
|
+
BarkestCore::DateParser.parse_for_date_column value
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
##
|
|
102
|
+
# Parses a value for storage in a datetime column.
|
|
103
|
+
#
|
|
104
|
+
# Value should be a string in 'M/D/YYYY HH:MM:SS' or 'YYYY-MM-DD HH:MM:SS' format, but can also be a Date or Time object.
|
|
105
|
+
#
|
|
106
|
+
# Returns a Time object or nil if value is invalid.
|
|
107
|
+
#
|
|
108
|
+
def self.parse_for_time_column(value)
|
|
109
|
+
BarkestCore::DateParser.parse_for_time_column value
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
##
|
|
113
|
+
# Parses a value for use in a SQL query.
|
|
114
|
+
#
|
|
115
|
+
# Returns NULL if the parsed date is nil.
|
|
116
|
+
# Otherwise returns the date in 'YYYY-MM-DD' format.
|
|
117
|
+
#
|
|
118
|
+
def self.parse_for_date_filter(value)
|
|
119
|
+
BarkestCore::DateParser.parse_for_date_filter value
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
##
|
|
123
|
+
# Parses a value for use in a SQL query.
|
|
124
|
+
#
|
|
125
|
+
# Returns NULL if the parsed time is nil.
|
|
126
|
+
# Otherwise returns the time in 'YYYY-MM-DD HH:MM:SS' format.
|
|
127
|
+
#
|
|
128
|
+
def self.parse_for_time_filter(value)
|
|
129
|
+
BarkestCore::DateParser.parse_for_time_filter value
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
protected
|
|
137
|
+
|
|
138
|
+
##
|
|
139
|
+
# Parses a value for storage in a date/datetime column.
|
|
140
|
+
#
|
|
141
|
+
# Value should be a string in 'M/D/YYYY' or 'YYYY-MM-DD' format but can also be a Date or Time object.
|
|
142
|
+
#
|
|
143
|
+
# Returns a Time object or nil if value is invalid.
|
|
144
|
+
#
|
|
145
|
+
def parse_for_date_column(value)
|
|
146
|
+
BarkestCore::DateParser.parse_for_date_column value
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
##
|
|
150
|
+
# Parses a value for storage in a datetime column.
|
|
151
|
+
#
|
|
152
|
+
# Value should be a string in 'M/D/YYYY HH:MM:SS' or 'YYYY-MM-DD HH:MM:SS' format, but can also be a Date or Time object.
|
|
153
|
+
#
|
|
154
|
+
# Returns a Time object or nil if value is invalid.
|
|
155
|
+
#
|
|
156
|
+
def parse_for_time_column(value)
|
|
157
|
+
BarkestCore::DateParser.parse_for_time_column value
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
##
|
|
161
|
+
# Parses a value for use in a SQL query.
|
|
162
|
+
#
|
|
163
|
+
# Returns NULL if the parsed date is nil.
|
|
164
|
+
# Otherwise returns the date in 'YYYY-MM-DD' format.
|
|
165
|
+
#
|
|
166
|
+
def parse_for_date_filter(value)
|
|
167
|
+
BarkestCore::DateParser.parse_for_date_filter value
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
##
|
|
171
|
+
# Parses a value for use in a SQL query.
|
|
172
|
+
#
|
|
173
|
+
# Returns NULL if the parsed time is nil.
|
|
174
|
+
# Otherwise returns the time in 'YYYY-MM-DD HH:MM:SS' format.
|
|
175
|
+
#
|
|
176
|
+
def parse_for_time_filter(value)
|
|
177
|
+
BarkestCore::DateParser.parse_for_time_filter value
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
end
|
|
181
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
require 'resolv'
|
|
2
|
+
|
|
3
|
+
module BarkestCore
|
|
4
|
+
|
|
5
|
+
##
|
|
6
|
+
# Adds helper methods to the model to allow verifying email addresses.
|
|
7
|
+
module EmailTester
|
|
8
|
+
|
|
9
|
+
##
|
|
10
|
+
# A regex that can be used to verify most email addresses.
|
|
11
|
+
#
|
|
12
|
+
# When used, the match will include a USER and DOMAIN element to represent the broken down email address.
|
|
13
|
+
VALID_EMAIL_REGEX = /\A(?<USER>[\w+\-.]+)@(?<DOMAIN>[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+)\z/i
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
##
|
|
17
|
+
# Validates the supplied email address against the VALID_EMAIL_REGEX.
|
|
18
|
+
#
|
|
19
|
+
# The +check_dns+ option ensures that an MX record can be found for the email address.
|
|
20
|
+
def self.valid_email?(email, check_dns = false)
|
|
21
|
+
match = VALID_EMAIL_REGEX.match(email)
|
|
22
|
+
return false unless match
|
|
23
|
+
if check_dns
|
|
24
|
+
return false if Resolv::DNS.open{ |dns| dns.getresources match['DOMAIN'], Resolv::DNS::Resource::IN::MX }.blank?
|
|
25
|
+
end
|
|
26
|
+
true
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# :nodoc:
|
|
30
|
+
def self.included(base)
|
|
31
|
+
base.class_eval do
|
|
32
|
+
##
|
|
33
|
+
# Validates the supplied email address against the VALID_EMAIL_REGEX.
|
|
34
|
+
#
|
|
35
|
+
# The +check_dns+ option ensures that an MX record can be found for the email address.
|
|
36
|
+
def self.valid_email?(email, check_dns = false)
|
|
37
|
+
BarkestCore::EmailTester.valid_email? email, check_dns
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
protected
|
|
44
|
+
|
|
45
|
+
##
|
|
46
|
+
# Validates the supplied email address against the VALID_EMAIL_REGEX.
|
|
47
|
+
#
|
|
48
|
+
# The +check_dns+ option ensures that an MX record can be found for the email address.
|
|
49
|
+
def valid_email?(email, check_dns = false)
|
|
50
|
+
BarkestCore::EmailTester.valid_email? email, check_dns
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
require 'encrypted_strings'
|
|
2
|
+
|
|
3
|
+
module BarkestCore
|
|
4
|
+
|
|
5
|
+
##
|
|
6
|
+
# Adds helper methods to the model to allow easy manipulation of fields stored as encrypted values.
|
|
7
|
+
#
|
|
8
|
+
# The encryption password is specified in +secrets.yml+.
|
|
9
|
+
#
|
|
10
|
+
# For a class MyNamespace::MyClass you can specify the encryption password using +my_namespace_my_class+
|
|
11
|
+
# or +my_class+ keys in the appropriate section of +secrets.yml+.
|
|
12
|
+
#
|
|
13
|
+
# If no specific encryption password is provided, then +secret_key_base+ is used instead.
|
|
14
|
+
#
|
|
15
|
+
module EncryptedFields
|
|
16
|
+
|
|
17
|
+
# :nodoc:
|
|
18
|
+
def self.included(base)
|
|
19
|
+
base.class_eval do
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def self.crypto_password
|
|
24
|
+
@crypto_password ||=
|
|
25
|
+
begin
|
|
26
|
+
klass = self.class.name.to_s.underscore
|
|
27
|
+
if klass.include?('/')
|
|
28
|
+
Rails.application.secrets[klass.gsub('/','_').to_sym] ||
|
|
29
|
+
Rails.application.secrets[klass.rpartition('/')[2].to_sym] ||
|
|
30
|
+
Rails.application.secrets[:secret_key_base]
|
|
31
|
+
else
|
|
32
|
+
Rails.application.secrets[klass.to_sym] ||
|
|
33
|
+
Rails.application.secrets[:secret_key_base]
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def self.crypto_cipher
|
|
39
|
+
@crypto_cipher ||= EncryptedStrings::SymmetricCipher.new(password: crypto_password)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def self.decrypt_value(value)
|
|
43
|
+
return nil if value.nil?
|
|
44
|
+
return '' if value == ''
|
|
45
|
+
crypto_cipher.decrypt(value)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
public
|
|
49
|
+
|
|
50
|
+
##
|
|
51
|
+
# Encrypts a value using this model's key.
|
|
52
|
+
#
|
|
53
|
+
# Will not encrypt nil or empty strings.
|
|
54
|
+
def self.encrypt_value(value)
|
|
55
|
+
return nil if value.nil?
|
|
56
|
+
return '' if value == ''
|
|
57
|
+
crypto_cipher.encrypt(value)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
protected
|
|
61
|
+
|
|
62
|
+
##
|
|
63
|
+
# Defines methods to allow accessing an encrypted field easily.
|
|
64
|
+
#
|
|
65
|
+
# Simplest usage:
|
|
66
|
+
# encrypted_field :encrypted_field_name
|
|
67
|
+
#
|
|
68
|
+
# Detailed usage:
|
|
69
|
+
# encrypted_field :encrypted => :encrypted_field_name,
|
|
70
|
+
# :decrypted => :field_name,
|
|
71
|
+
# :read_only => false
|
|
72
|
+
#
|
|
73
|
+
# In both usages, the model will receive two new methods:
|
|
74
|
+
# def field_name
|
|
75
|
+
# ...
|
|
76
|
+
# end
|
|
77
|
+
#
|
|
78
|
+
# def field_name=(value)
|
|
79
|
+
# ...
|
|
80
|
+
# end
|
|
81
|
+
#
|
|
82
|
+
# If you specify :read_only => true, then only one method will be defined:
|
|
83
|
+
# def field_name
|
|
84
|
+
# ...
|
|
85
|
+
# end
|
|
86
|
+
#
|
|
87
|
+
# Raises a StandardError if the attribute names cannot be determined or if the
|
|
88
|
+
# encrypted attribute is not defined.
|
|
89
|
+
#
|
|
90
|
+
def self.encrypted_field(options = {})
|
|
91
|
+
unless options.is_a?(Hash)
|
|
92
|
+
attr_name = options.to_s
|
|
93
|
+
if attr_name[0...10] == 'encrypted_' ||
|
|
94
|
+
attr_name[0...4] == 'enc_' ||
|
|
95
|
+
attr_name[-4..-1] == '_enc' ||
|
|
96
|
+
attr_name[-10..-1] == '_encrypted'
|
|
97
|
+
options = {
|
|
98
|
+
encrypted: attr_name
|
|
99
|
+
}
|
|
100
|
+
else
|
|
101
|
+
options = {
|
|
102
|
+
decrypted: attr_name
|
|
103
|
+
}
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
raise StandardError.new('Options must contain either :decrypted or :encrypted key.') if options[:encrypted].blank? && options[:decrypted].blank?
|
|
108
|
+
|
|
109
|
+
if options[:encrypted].blank?
|
|
110
|
+
attr_name = options[:decrypted]
|
|
111
|
+
%W(encrypted_#{attr_name} enc_#{attr_name} #{attr_name}_enc #{attr_name}_encrypted).each do |attr|
|
|
112
|
+
if method_defined?(attr) || columns.find{|a| a.name == attr}
|
|
113
|
+
options[:encrypted] = attr
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
elsif options[:decrypted].blank?
|
|
117
|
+
attr_name = options[:encrypted]
|
|
118
|
+
if attr_name[0...10] == 'encrypted_' || attr_name[0...4] == 'enc_'
|
|
119
|
+
options[:decrypted] = attr_name.partition('_')[2]
|
|
120
|
+
elsif attr_name[-4..-1] == '_enc' || attr_name[-10..-1] == '_encrypted'
|
|
121
|
+
options[:decrypted] = attr_name.rpartition('_')[0]
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
raise StandardError.new("Cannot locate encrypted attribute with #{options[:decrypted]} as the decypted attribute name.") if options[:encrypted].blank?
|
|
126
|
+
raise StandardError.new("Cannot determine decrypted attribute name with #{options[:encrypted]} as the encrypted attribute.") if options[:decrypted].blank?
|
|
127
|
+
|
|
128
|
+
define_method options[:decrypted].to_sym do
|
|
129
|
+
self.class.decrypt_value send(options[:encrypted])
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
unless options[:read_only]
|
|
133
|
+
define_method :"#{options[:decrypted]}=" do |value|
|
|
134
|
+
send "#{options[:encrypted]}=", self.class.encrypt_value(value)
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
##
|
|
141
|
+
# Encrypts a value and returns the result in base64 encoding.
|
|
142
|
+
def encrypt(value)
|
|
143
|
+
self.class.encrypt_value(value)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
##
|
|
147
|
+
# Decodes a base64 value and returns the decrypted value.
|
|
148
|
+
def decrypt(value)
|
|
149
|
+
self.class.decrypt_value(value)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
end
|
|
156
|
+
end
|