barkest_core 1.5.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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,70 @@
|
|
1
|
+
module BarkestCore
|
2
|
+
##
|
3
|
+
# This module contains some helper functions to make generating common HTML elements easier.
|
4
|
+
module HtmlHelper
|
5
|
+
|
6
|
+
##
|
7
|
+
# Creates a glyph icon using the specified +name+ and +size+.
|
8
|
+
#
|
9
|
+
# The +size+ can be nil, :small, :smaller, :big, or :bigger.
|
10
|
+
# The default size is nil.
|
11
|
+
def glyph(name, size = nil)
|
12
|
+
size = size.to_s.downcase
|
13
|
+
if %w(small smaller big bigger).include?(size)
|
14
|
+
size = ' glyph-' + size
|
15
|
+
else
|
16
|
+
size = ''
|
17
|
+
end
|
18
|
+
"<i class=\"glyphicon glyphicon-#{h name}#{size}\"></i>".html_safe
|
19
|
+
end
|
20
|
+
|
21
|
+
##
|
22
|
+
# Creates a check glyph icon if the +bool_val+ is true.
|
23
|
+
#
|
24
|
+
# The +size+ can be nil, :small, :smaller, :big, or :bigger.
|
25
|
+
# The default +size+ is :small.
|
26
|
+
def check_if(bool_val, size = :small)
|
27
|
+
glyph(:ok, size) if bool_val
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# Creates a panel with the specified title.
|
32
|
+
#
|
33
|
+
# Valid options:
|
34
|
+
# * +type+ can be +primary+, +success+, +info+, +warning+, or +danger+. Default: primary
|
35
|
+
# * +size+ can be any value from 1..12. Default: 6
|
36
|
+
# * +offset+ can be any value from 0..12. Default: 3
|
37
|
+
# * +open_body+ can be true or false. If true, the body division is opened (and closed) by this helper. Default: true
|
38
|
+
#
|
39
|
+
# Provide a block to render content within the panel.
|
40
|
+
def panel(title, options = { }, &block)
|
41
|
+
options = {
|
42
|
+
type: 'primary',
|
43
|
+
size: 6,
|
44
|
+
offset: 3,
|
45
|
+
open_body: true
|
46
|
+
}.merge(options || {})
|
47
|
+
|
48
|
+
options[:type] = options[:type].to_s.downcase
|
49
|
+
options[:type] = 'primary' unless %w(primary success info warning danger).include?(options[:type])
|
50
|
+
options[:size] = 6 unless (1..12).include?(options[:size])
|
51
|
+
options[:offset] = 3 unless (0..12).include?(options[:offset])
|
52
|
+
|
53
|
+
ret = "<div class=\"col-md-#{options[:size]} col-md-offset-#{options[:offset]}\"><div class=\"panel panel-#{options[:type]}\"><div class=\"panel-heading\"><h4 class=\"panel-title\">#{h title}</h4></div>"
|
54
|
+
ret += '<div class="panel-body">' if options[:open_body]
|
55
|
+
|
56
|
+
if block_given?
|
57
|
+
content = capture { block.call }
|
58
|
+
ret += h content.to_s
|
59
|
+
end
|
60
|
+
|
61
|
+
ret += '</div>' if options[:open_body]
|
62
|
+
ret += '</div></div>'
|
63
|
+
|
64
|
+
ret.html_safe
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module BarkestCore
|
2
|
+
##
|
3
|
+
# Contains some miscellaneous helper methods.
|
4
|
+
module MiscHelper
|
5
|
+
|
6
|
+
##
|
7
|
+
# Formats a date in M/D/YYYY format.
|
8
|
+
#
|
9
|
+
# The +date+ can be either a string already in the correct format, or a Date/Time object.
|
10
|
+
# If +date+ is blank or nil, then nil will be returned.
|
11
|
+
#
|
12
|
+
def fmt_date(date)
|
13
|
+
return nil if date.blank?
|
14
|
+
return nil unless (date.is_a?(String) || date.is_a?(Date) || date.is_a?(Time))
|
15
|
+
unless date.is_a?(String)
|
16
|
+
date = date.to_s(:date4)
|
17
|
+
end
|
18
|
+
m,d,y = date.split('/')
|
19
|
+
"#{m.to_i}/#{d.to_i}/#{y.to_i}"
|
20
|
+
end
|
21
|
+
|
22
|
+
##
|
23
|
+
# Formats a number to the specified number of decimal places.
|
24
|
+
#
|
25
|
+
# The +value+ can be either any valid numeric expression that can be converted to a float.
|
26
|
+
#
|
27
|
+
def fixed(value, places = 2)
|
28
|
+
value = value.to_s.to_f unless value.is_a?(Float)
|
29
|
+
sprintf("%0.#{places}f", value.round(places))
|
30
|
+
end
|
31
|
+
|
32
|
+
##
|
33
|
+
# Splits a name into First, Middle, and Last parts.
|
34
|
+
#
|
35
|
+
# Returns an array containing [ First, Middle, Last ]
|
36
|
+
# Any part that is missing will be nil.
|
37
|
+
#
|
38
|
+
# 'John Doe' => [ 'John', nil, 'Doe' ]
|
39
|
+
# 'Doe, John' => [ 'John', nil, 'Doe' ]
|
40
|
+
# 'John A. Doe' => [ 'John', 'A.', 'Doe' ]
|
41
|
+
# 'Doe, John A.' => [ 'John', 'A.', 'Doe' ]
|
42
|
+
# 'John A. Doe Jr.' => [ 'John', 'A.', 'Doe Jr.' ]
|
43
|
+
# 'Doe Jr., John A.' => [ 'John', 'A.', 'Doe Jr.' ]
|
44
|
+
#
|
45
|
+
# Since it doesn't check very hard, there are some known bugs as well.
|
46
|
+
#
|
47
|
+
# 'John Doe Jr.' => [ 'John', 'Doe', 'Jr.' ]
|
48
|
+
# 'John Doe, Jr.' => [ 'Jr.', nil, 'John Doe' ]
|
49
|
+
# 'Doe, John A., Jr.' => [ 'John', 'A., Jr.', 'Doe' ]
|
50
|
+
#
|
51
|
+
# It should work in most cases.
|
52
|
+
#
|
53
|
+
def split_name(name)
|
54
|
+
name ||= ''
|
55
|
+
if name.include?(',')
|
56
|
+
last,first = name.split(',', 2)
|
57
|
+
first,middle = first.to_s.strip.split(' ', 2)
|
58
|
+
else
|
59
|
+
first,middle,last = name.split(' ', 3)
|
60
|
+
if middle && !last
|
61
|
+
middle,last = last,middle
|
62
|
+
end
|
63
|
+
end
|
64
|
+
[ first.to_s.strip, middle.to_s.strip, last.to_s.strip ]
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
require 'prawn-rails/document'
|
2
|
+
require 'prawn/measurement_extensions'
|
3
|
+
require 'prawn/font'
|
4
|
+
|
5
|
+
module BarkestCore
|
6
|
+
##
|
7
|
+
# This module defines the method that makes PDF generation just a bit easier.
|
8
|
+
#
|
9
|
+
module PdfHelper
|
10
|
+
|
11
|
+
##
|
12
|
+
# Creates a PDF document with the specified options.
|
13
|
+
#
|
14
|
+
# The document will be setup with configured margins, a 100x100 grid, and one embedded font (ArhivoNarrow).
|
15
|
+
# Once the document is configured, the +pdf+ will be yielded to the block provided to generate the content.
|
16
|
+
#
|
17
|
+
# Accepted options:
|
18
|
+
#
|
19
|
+
# page_layout::
|
20
|
+
# Specify the page layout. This can be either :portrait or :landscape. Defaults to :portrait.
|
21
|
+
#
|
22
|
+
# page_size::
|
23
|
+
# Specify the page size. This defaults to 'LETTER'. See {Prawn PDF Manual}[http://prawnpdf.org/manual.pdf#page=91] for more information.
|
24
|
+
#
|
25
|
+
# margin::
|
26
|
+
# Specify the margin size. This can be either a single value or an array of values. Internally it always
|
27
|
+
# gets converted to an array of values. If you only specify a single value, it will be filled out as the
|
28
|
+
# margin for all four edges. Alternatively, you can set :top_margin, :right_margin, :left_margin, and
|
29
|
+
# :bottom_margin individually.
|
30
|
+
#
|
31
|
+
# top_margin::
|
32
|
+
# Specify the top margin size. Defaults to 0.5 in.
|
33
|
+
#
|
34
|
+
# right_margin::
|
35
|
+
# Specify the right margin size. Defaults to 0.5 in.
|
36
|
+
#
|
37
|
+
# left_margin::
|
38
|
+
# Specify the left margin size. Defaults to 0.5 in.
|
39
|
+
#
|
40
|
+
# bottom_margin::
|
41
|
+
# Specify the bottom margin size. Defaults to 0.5 in.
|
42
|
+
#
|
43
|
+
# print_scaling::
|
44
|
+
# Allows you to specify the default print scaling in the print dialog. Defaults to :none.
|
45
|
+
# See the {Prawn PDF Manual}[http://prawnpdf.org/manual.pdf#page=95] for more information.
|
46
|
+
#
|
47
|
+
# font_name::
|
48
|
+
# Specify the default font for the document. Can be one of 'Helvetica', 'Times-Roman', 'Courier', or
|
49
|
+
# 'ArchivoNarrow'. Defaults to 'Helvetica'.
|
50
|
+
#
|
51
|
+
# font_size::
|
52
|
+
# Specify the default font size for the document. Defaults to 10 pt.
|
53
|
+
#
|
54
|
+
# skip_footer::
|
55
|
+
# Set to true to skip footer generation. Otherwise, once you finish generating content, a footer will
|
56
|
+
# be attached to every page automatically.
|
57
|
+
#
|
58
|
+
# footer_left::
|
59
|
+
# Set the left footer text. Defaults to the current user name and time.
|
60
|
+
#
|
61
|
+
# footer_center::
|
62
|
+
# Set the center footer text. Defaults to the request path.
|
63
|
+
#
|
64
|
+
# footer_right::
|
65
|
+
# Set the right footer text. Defaults to "Page # of #".
|
66
|
+
#
|
67
|
+
# footer_hr::
|
68
|
+
# Set to true to draw a horizontal rule above the footer, or false to omit the horizontal rule.
|
69
|
+
# Defaults to true.
|
70
|
+
#
|
71
|
+
# footer_color::
|
72
|
+
# Set the color of the footer text. Defaults to '000000' (black).
|
73
|
+
#
|
74
|
+
def pdf_doc(options = {})
|
75
|
+
|
76
|
+
# our default values merged with the configured values and then the options provided.
|
77
|
+
options = {
|
78
|
+
page_layout: :portrait,
|
79
|
+
page_size: 'LETTER',
|
80
|
+
margin: [ 0.5.in, 0.5.in, 0.55.in, 0.5.in ],
|
81
|
+
print_scaling: :none,
|
82
|
+
font_name: 'Helvetica',
|
83
|
+
font_size: 10.0
|
84
|
+
}.merge(PrawnRails.config.to_h).merge(options || {})
|
85
|
+
|
86
|
+
# build the info
|
87
|
+
options[:info] ||= {}
|
88
|
+
options[:info].merge!({
|
89
|
+
Title: options.delete(:title) || "#{controller_name}##{action_name}",
|
90
|
+
Creator: options.delete(:creator) || Rails.application.app_company,
|
91
|
+
Producer: options.delete(:producer) || Rails.application.app_info,
|
92
|
+
CreationDate: options.delete(:creation_date) || Time.now
|
93
|
+
})
|
94
|
+
|
95
|
+
# build the margin array
|
96
|
+
options[:margin] ||= []
|
97
|
+
options[:margin] = [ options[:margin] ] * 4 unless options[:margin].is_a?(Array)
|
98
|
+
|
99
|
+
# top margin defaults to 0.5".
|
100
|
+
options[:margin][0] = options[:top_margin] if options[:top_margin]
|
101
|
+
options[:margin][0] = 0.5.in unless options[:margin][0]
|
102
|
+
|
103
|
+
# right margin defaults to top margin.
|
104
|
+
options[:margin][1] = options[:right_margin] if options[:right_margin]
|
105
|
+
options[:margin][1] = options[:margin][0] unless options[:margin][1]
|
106
|
+
|
107
|
+
# bottom margin defaults to top margin.
|
108
|
+
options[:margin][2] = options[:bottom_margin] if options[:bottom_margin]
|
109
|
+
options[:margin][2] = options[:margin][0] unless options[:margin][2]
|
110
|
+
|
111
|
+
# left margin defaults to right margin.
|
112
|
+
options[:margin][3] = options[:left_margin] if options[:left_margin]
|
113
|
+
options[:margin][3] = options[:margin][1] unless options[:margin][3]
|
114
|
+
|
115
|
+
font_name = options[:font_name] || 'Helvetica'
|
116
|
+
font_size = options[:font_size] || 10.0
|
117
|
+
|
118
|
+
skip_footer = options[:skip_footer].nil? ? false : options[:skip_footer]
|
119
|
+
|
120
|
+
footer_left = options[:footer_left].nil? ? "#{current_user.name} - #{Time.zone.now.strftime('%Y-%m-%d %H:%M:%S')}" : options[:footer_left].to_s
|
121
|
+
footer_center = options[:footer_center].nil? ? request.fullpath : options[:footer_center].to_s
|
122
|
+
footer_right = options[:footer_right].nil? ? nil : options[:footer_right].to_s
|
123
|
+
footer_hr = options[:footer_hr].nil? ? true : options[:footer_hr]
|
124
|
+
footer_color = options[:footer_color].nil? ? '000000' : options[:footer_color].to_s
|
125
|
+
|
126
|
+
# remove some options that are custom.
|
127
|
+
options.except!(
|
128
|
+
:title, :creator, :producer, :creation_date,
|
129
|
+
:top_margin, :bottom_margin, :left_margin, :right_margin,
|
130
|
+
:font_name, :font_size,
|
131
|
+
:skip_footer
|
132
|
+
)
|
133
|
+
|
134
|
+
left_edge = options[:margin][3]
|
135
|
+
right_edge = options[:margin][1]
|
136
|
+
bottom_edge = options[:margin][2]
|
137
|
+
|
138
|
+
pdf = PrawnRails::Document.new(options)
|
139
|
+
|
140
|
+
# ArchivoNarrow gives us another sans font that has tighter letter spacing, and it is also a freely available font requiring no licensing.
|
141
|
+
pdf.font_families['ArchivoNarrow'] = {
|
142
|
+
bold: { file: pdf.asset_font_path('barkest_core/ArchivoNarrow-Bold.ttf') },
|
143
|
+
italic: { file: pdf.asset_font_path('barkest_core/ArchivoNarrow-Italic.ttf') },
|
144
|
+
bold_italic: { file: pdf.asset_font_path('barkest_core/ArchivoNarrow-BoldItalic.ttf') },
|
145
|
+
normal: { file: pdf.asset_font_path('barkest_core/ArchivoNarrow-Regular.ttf') },
|
146
|
+
}
|
147
|
+
|
148
|
+
# set the default font and size
|
149
|
+
pdf.font font_name, size: font_size
|
150
|
+
|
151
|
+
# nice fine grid layout.
|
152
|
+
pdf.define_grid columns: 100, rows: 100, gutter: 2.5
|
153
|
+
|
154
|
+
yield pdf if block_given?
|
155
|
+
|
156
|
+
unless skip_footer
|
157
|
+
pdf.font font_name, size: 8.0 do
|
158
|
+
(1..pdf.page_count).each do |pg|
|
159
|
+
pdf.go_to_page pg
|
160
|
+
pdf.canvas do
|
161
|
+
width = pdf.bounds.right - right_edge - left_edge
|
162
|
+
if footer_hr
|
163
|
+
pdf.stroke_color '000000'
|
164
|
+
pdf.stroke { pdf.horizontal_line left_edge, pdf.bounds.right - right_edge, at: bottom_edge }
|
165
|
+
end
|
166
|
+
pos = [ left_edge, bottom_edge - 3 ]
|
167
|
+
pdf.bounding_box(pos, width: width, height: 12) { pdf.text pdf.footer_values[0] || footer_left, align: :left, color: footer_color }
|
168
|
+
pdf.bounding_box(pos, width: width, height: 12) { pdf.text pdf.footer_values[1] || footer_center, align: :center, color: footer_color }
|
169
|
+
pdf.bounding_box(pos, width: width, height: 12) { pdf.text pdf.footer_values[2] || (footer_right || "Page #{pg} of #{pdf.page_count}"), align: :right, color: footer_color }
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
pdf.render
|
176
|
+
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
module BarkestCore
|
2
|
+
##
|
3
|
+
# This module makes it easy to work with Google's recaptcha service.
|
4
|
+
#
|
5
|
+
# Simply add +recaptcha_public_key+ and +recaptch_private_key+ to your
|
6
|
+
# +secrets.yml+ configuration file, or provide +RECAPTCHA_PUBLIC_KEY+
|
7
|
+
# and +RECAPTCHA_PRIVATE_KEY+ environment variables.
|
8
|
+
module RecaptchaHelper
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def load_recaptcha_keys
|
13
|
+
tmp = ENV['RECAPTCHA_PUBLIC_KEY'].to_s
|
14
|
+
@recaptcha_site_key = tmp.blank? ? Rails.application.secrets[:recaptcha_public_key].to_s : tmp
|
15
|
+
tmp = ENV['RECAPTCHA_PRIVATE_KEY'].to_s
|
16
|
+
@recaptcha_secret_key = tmp.blank? ? Rails.application.secrets[:recaptcha_private_key].to_s : tmp
|
17
|
+
end
|
18
|
+
|
19
|
+
def recaptcha_site_key
|
20
|
+
load_recaptcha_keys unless @recaptcha_site_key
|
21
|
+
@recaptcha_site_key
|
22
|
+
end
|
23
|
+
|
24
|
+
def recaptcha_secret_key
|
25
|
+
load_recaptcha_keys unless @recaptcha_secret_key
|
26
|
+
@recaptcha_secret_key
|
27
|
+
end
|
28
|
+
|
29
|
+
def recaptcha_disabled?
|
30
|
+
Rails.env.test? || recaptcha_site_key.blank? || recaptcha_secret_key.blank?
|
31
|
+
end
|
32
|
+
|
33
|
+
public
|
34
|
+
|
35
|
+
##
|
36
|
+
# Adds the recaptcha challenge to a form.
|
37
|
+
#
|
38
|
+
# This will include the recaptcha API from Google automatically and inserts a +<br>+ sequence after the challenge
|
39
|
+
# if +include_break+ is set to true (the default).
|
40
|
+
def add_recaptcha_challenge(include_break = true)
|
41
|
+
unless recaptcha_disabled?
|
42
|
+
"<div class=\"g-recaptcha\" data-sitekey=\"#{h recaptcha_site_key}\"></div>\n<script src=\"https://www.google.com/recaptcha/api.js\"></script>#{include_break ? '<br>' : ''}".html_safe
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
##
|
47
|
+
# Verifies the response from a recaptcha challenge in a controller.
|
48
|
+
#
|
49
|
+
# It will return true if the recaptcha challenge passed. It always returns true in the 'test' environment.
|
50
|
+
#
|
51
|
+
# If a +model+ is provided, then an error will be added to the model if the challenge fails.
|
52
|
+
# Because this is handled outside of the model (since it's based on the request and not the model),
|
53
|
+
# you should first check if the model is valid and then verify the recaptcha challenge to ensure you
|
54
|
+
# don't lose the recaptcha error message.
|
55
|
+
#
|
56
|
+
# if model.valid? && verify_recaptcha_challenge(model)
|
57
|
+
# model.save
|
58
|
+
# redirect_to :show, id: model
|
59
|
+
# else
|
60
|
+
# render 'edit'
|
61
|
+
# end
|
62
|
+
#
|
63
|
+
def verify_recaptcha_challenge(model = nil)
|
64
|
+
|
65
|
+
# always true in tests.
|
66
|
+
return true if recaptcha_disabled?
|
67
|
+
|
68
|
+
# model must respond to the 'errors' message and the result of that must respond to 'add'
|
69
|
+
if !model || !model.respond_to?('errors') || !model.send('errors').respond_to?('add')
|
70
|
+
model = nil
|
71
|
+
end
|
72
|
+
|
73
|
+
begin
|
74
|
+
recaptcha = nil
|
75
|
+
|
76
|
+
http = Net::HTTP
|
77
|
+
|
78
|
+
remote_ip = (request.respond_to?('remote_ip') && request.send('remote_ip')) || (env && env['REMOTE_ADDR'])
|
79
|
+
verify_hash = {
|
80
|
+
secret: recaptcha_secret_key,
|
81
|
+
remoteip: remote_ip,
|
82
|
+
response: params['g-recaptcha-response']
|
83
|
+
}
|
84
|
+
|
85
|
+
Timeout::timeout(5) do
|
86
|
+
uri = URI.parse('https://www.google.com/recaptcha/api/siteverify')
|
87
|
+
http_instance = http.new(uri.host, uri.port)
|
88
|
+
if uri.port == 443
|
89
|
+
http_instance.use_ssl = true
|
90
|
+
http_instance.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
91
|
+
end
|
92
|
+
request = Net::HTTP::Post.new(uri.request_uri)
|
93
|
+
request.set_form_data(verify_hash)
|
94
|
+
recaptcha = http_instance.request(request)
|
95
|
+
end
|
96
|
+
answer = JSON.parse(recaptcha.body)
|
97
|
+
|
98
|
+
if answer['success'].to_s.downcase == 'true'
|
99
|
+
return true
|
100
|
+
else
|
101
|
+
if model
|
102
|
+
model.errors.add(:base, 'Recaptcha verification failed.')
|
103
|
+
end
|
104
|
+
return false
|
105
|
+
end
|
106
|
+
|
107
|
+
rescue Timeout::Error
|
108
|
+
if model
|
109
|
+
model.errors.add(:base, 'Recaptcha unreachable.')
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module BarkestCore
|
2
|
+
##
|
3
|
+
# This module adds +log_in+, +log_out+, +current_user+, and other session related helper methods.
|
4
|
+
#
|
5
|
+
# Based on the tutorial from [www.railstutorial.org](www.railstutorial.org).
|
6
|
+
module SessionsHelper
|
7
|
+
|
8
|
+
##
|
9
|
+
# Logs in the given user.
|
10
|
+
def log_in(user)
|
11
|
+
session[:user_id] = user.id
|
12
|
+
end
|
13
|
+
|
14
|
+
##
|
15
|
+
# Logs out any currently logged in user.
|
16
|
+
def log_out
|
17
|
+
forget current_user
|
18
|
+
session.delete(:user_id)
|
19
|
+
@current_user = nil
|
20
|
+
end
|
21
|
+
|
22
|
+
##
|
23
|
+
# Gets the current user.
|
24
|
+
def current_user
|
25
|
+
if (user_id = session[:user_id])
|
26
|
+
@current_user ||= User.find_by(id: user_id)
|
27
|
+
elsif (user_id = cookies.signed[:user_id])
|
28
|
+
user = User.find_by(id: user_id)
|
29
|
+
if user && user.authenticated?(:remember, cookies[:remember_token])
|
30
|
+
log_in user
|
31
|
+
@current_user = user
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
# Is the specified user the current user?
|
38
|
+
def current_user?(user)
|
39
|
+
user == current_user
|
40
|
+
end
|
41
|
+
|
42
|
+
##
|
43
|
+
# Is the current user a system administrator?
|
44
|
+
def system_admin?
|
45
|
+
current_user && current_user.system_admin?
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Is a user currently logged in?
|
50
|
+
def logged_in?
|
51
|
+
!current_user.nil?
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# Stores the user id to the permanent cookies to keep the user logged in.
|
56
|
+
def remember(user)
|
57
|
+
user.remember
|
58
|
+
cookies.permanent.signed[:user_id] = user.id
|
59
|
+
cookies.permanent[:remember_token] = user.remember_token
|
60
|
+
end
|
61
|
+
|
62
|
+
##
|
63
|
+
# Removes the user from the permanent cookies.
|
64
|
+
def forget(user)
|
65
|
+
user.forget
|
66
|
+
cookies.delete(:user_id)
|
67
|
+
cookies.delete(:remember_token)
|
68
|
+
end
|
69
|
+
|
70
|
+
##
|
71
|
+
# A helper redirect method primarily used after logon to redirect to the page that requested a logon.
|
72
|
+
#
|
73
|
+
# There may be other uses, but logon is the most likely use case.
|
74
|
+
def redirect_back_or(default)
|
75
|
+
redirect_to(session[:forwarding_url] || default)
|
76
|
+
session.delete(:forwarding_url)
|
77
|
+
end
|
78
|
+
|
79
|
+
##
|
80
|
+
# Stores the current request URL to the session for use with +redirect_back_or+.
|
81
|
+
#
|
82
|
+
def store_location
|
83
|
+
session[:forwarding_url] = request.url if request.get?
|
84
|
+
end
|
85
|
+
|
86
|
+
##
|
87
|
+
# Stores the current request URL to the session and redirects to the specified URL.
|
88
|
+
def store_location_and_redirect_to(url)
|
89
|
+
store_location
|
90
|
+
redirect_to url
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|