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.
Files changed (308) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/Gemfile +22 -0
  4. data/Gemfile.lock +254 -0
  5. data/MIT-LICENSE +20 -0
  6. data/README.md +364 -0
  7. data/Rakefile +37 -0
  8. data/app/assets/fonts/barkest_core/ArchivoNarrow-Bold.ttf +0 -0
  9. data/app/assets/fonts/barkest_core/ArchivoNarrow-BoldItalic.ttf +0 -0
  10. data/app/assets/fonts/barkest_core/ArchivoNarrow-Italic.ttf +0 -0
  11. data/app/assets/fonts/barkest_core/ArchivoNarrow-Regular.ttf +0 -0
  12. data/app/assets/images/barkest_core/.keep +0 -0
  13. data/app/assets/images/barkest_core/barcode-B.svg +181 -0
  14. data/app/assets/javascripts/barkest_core/.keep +0 -0
  15. data/app/assets/javascripts/barkest_core/application.js +22 -0
  16. data/app/assets/javascripts/barkest_core/bootstrap-datepicker.js +1800 -0
  17. data/app/assets/javascripts/barkest_core/field_init.js +7 -0
  18. data/app/assets/javascripts/barkest_core/jquery.doubleScroll.js +112 -0
  19. data/app/assets/javascripts/barkest_core/masked_edit.js +25 -0
  20. data/app/assets/javascripts/barkest_core/system_status.js.erb +201 -0
  21. data/app/assets/stylesheets/barkest_core/.keep +0 -0
  22. data/app/assets/stylesheets/barkest_core/application.css +17 -0
  23. data/app/assets/stylesheets/barkest_core/custom.css.scss +264 -0
  24. data/app/assets/stylesheets/barkest_core/datepicker3.css +790 -0
  25. data/app/controllers/.keep +0 -0
  26. data/app/controllers/access_groups_controller.rb +74 -0
  27. data/app/controllers/account_activations_controller.rb +29 -0
  28. data/app/controllers/application_controller.rb +5 -0
  29. data/app/controllers/barkest_core/application_controller_base.rb +113 -0
  30. data/app/controllers/barkest_core/engine_controller_base.rb +15 -0
  31. data/app/controllers/barkest_core/testsub_controller.rb +21 -0
  32. data/app/controllers/contact_controller.rb +32 -0
  33. data/app/controllers/log_view_controller.rb +31 -0
  34. data/app/controllers/password_resets_controller.rb +126 -0
  35. data/app/controllers/sessions_controller.rb +64 -0
  36. data/app/controllers/status_controller.rb +150 -0
  37. data/app/controllers/system_config_controller.rb +238 -0
  38. data/app/controllers/system_update_controller.rb +164 -0
  39. data/app/controllers/test_access_controller.rb +44 -0
  40. data/app/controllers/test_report_controller.rb +75 -0
  41. data/app/controllers/users_controller.rb +218 -0
  42. data/app/helpers/.keep +0 -0
  43. data/app/helpers/barkest_core/application_helper.rb +134 -0
  44. data/app/helpers/barkest_core/form_helper.rb +469 -0
  45. data/app/helpers/barkest_core/html_helper.rb +70 -0
  46. data/app/helpers/barkest_core/misc_helper.rb +68 -0
  47. data/app/helpers/barkest_core/pdf_helper.rb +180 -0
  48. data/app/helpers/barkest_core/recaptcha_helper.rb +115 -0
  49. data/app/helpers/barkest_core/sessions_helper.rb +94 -0
  50. data/app/helpers/barkest_core/status_helper.rb +118 -0
  51. data/app/helpers/barkest_core/users_helper.rb +32 -0
  52. data/app/mailers/.keep +0 -0
  53. data/app/mailers/application_mailer.rb +5 -0
  54. data/app/mailers/barkest_core/application_mailer_base.rb +30 -0
  55. data/app/mailers/barkest_core/contact_form.rb +20 -0
  56. data/app/mailers/barkest_core/user_mailer.rb +44 -0
  57. data/app/models/.keep +0 -0
  58. data/app/models/access_group.rb +121 -0
  59. data/app/models/access_group_group_member.rb +13 -0
  60. data/app/models/access_group_user_member.rb +11 -0
  61. data/app/models/barkest_core/auth_config.rb +95 -0
  62. data/app/models/barkest_core/authorize_failure.rb +7 -0
  63. data/app/models/barkest_core/contact_message.rb +37 -0
  64. data/app/models/barkest_core/database_config.rb +223 -0
  65. data/app/models/barkest_core/db_table.rb +21 -0
  66. data/app/models/barkest_core/email_config.rb +132 -0
  67. data/app/models/barkest_core/global_status.rb +267 -0
  68. data/app/models/barkest_core/log_entry.rb +101 -0
  69. data/app/models/barkest_core/log_view_options.rb +51 -0
  70. data/app/models/barkest_core/ms_sql_db_definition.rb +441 -0
  71. data/app/models/barkest_core/ms_sql_definition.rb +221 -0
  72. data/app/models/barkest_core/ms_sql_function.rb +423 -0
  73. data/app/models/barkest_core/not_logged_in.rb +7 -0
  74. data/app/models/barkest_core/pdf_table_builder.rb +407 -0
  75. data/app/models/barkest_core/self_update_config.rb +37 -0
  76. data/app/models/barkest_core/user_alert.rb +29 -0
  77. data/app/models/barkest_core/user_alert_generators.rb +58 -0
  78. data/app/models/barkest_core/user_manager.rb +404 -0
  79. data/app/models/barkest_core/work_path.rb +74 -0
  80. data/app/models/disable_user.rb +18 -0
  81. data/app/models/ldap_access_group.rb +15 -0
  82. data/app/models/system_config.rb +99 -0
  83. data/app/models/user.rb +405 -0
  84. data/app/models/user_login_history.rb +11 -0
  85. data/app/views/.keep +0 -0
  86. data/app/views/access_groups/_form.html.erb +19 -0
  87. data/app/views/access_groups/edit.html.erb +2 -0
  88. data/app/views/access_groups/index.html.erb +32 -0
  89. data/app/views/access_groups/new.html.erb +2 -0
  90. data/app/views/access_groups/show.html.erb +4 -0
  91. data/app/views/barkest_core/contact_form/contact.html.erb +16 -0
  92. data/app/views/barkest_core/contact_form/contact.text.erb +13 -0
  93. data/app/views/barkest_core/testsub/_links.html.erb +5 -0
  94. data/app/views/barkest_core/testsub/page1.html.erb +3 -0
  95. data/app/views/barkest_core/testsub/page2.html.erb +2 -0
  96. data/app/views/barkest_core/testsub/page3.html.erb +2 -0
  97. data/app/views/barkest_core/user_mailer/account_activation.html.erb +7 -0
  98. data/app/views/barkest_core/user_mailer/account_activation.text.erb +6 -0
  99. data/app/views/barkest_core/user_mailer/invalid_password_reset.html.erb +3 -0
  100. data/app/views/barkest_core/user_mailer/invalid_password_reset.text.erb +5 -0
  101. data/app/views/barkest_core/user_mailer/password_reset.html.erb +8 -0
  102. data/app/views/barkest_core/user_mailer/password_reset.text.erb +7 -0
  103. data/app/views/contact/index.html.erb +24 -0
  104. data/app/views/layouts/_footer_copyright.html.erb +1 -0
  105. data/app/views/layouts/_menu_admin.html.erb +5 -0
  106. data/app/views/layouts/_menu_anon.html.erb +0 -0
  107. data/app/views/layouts/_menu_auth.html.erb +3 -0
  108. data/app/views/layouts/_menu_footer.html.erb +1 -0
  109. data/app/views/layouts/_nav_logo.html.erb +1 -0
  110. data/app/views/layouts/application.html.erb +2 -0
  111. data/app/views/layouts/barkest_core/_application.html.erb +24 -0
  112. data/app/views/layouts/barkest_core/_footer.html.erb +18 -0
  113. data/app/views/layouts/barkest_core/_header.html.erb +38 -0
  114. data/app/views/layouts/barkest_core/_html_mailer.html.erb +11 -0
  115. data/app/views/layouts/barkest_core/_menu_account.html.erb +14 -0
  116. data/app/views/layouts/barkest_core/_menu_sample.html.erb +1 -0
  117. data/app/views/layouts/barkest_core/_messages.html.erb +4 -0
  118. data/app/views/layouts/barkest_core/_shim.html.erb +4 -0
  119. data/app/views/layouts/barkest_core/_subheader.html.erb +1 -0
  120. data/app/views/layouts/barkest_core/_text_mailer.text.erb +4 -0
  121. data/app/views/layouts/mailer.html.erb +1 -0
  122. data/app/views/layouts/mailer.text.erb +1 -0
  123. data/app/views/log_view/index.html.erb +100 -0
  124. data/app/views/password_resets/edit.html.erb +20 -0
  125. data/app/views/password_resets/new.html.erb +14 -0
  126. data/app/views/sessions/new.html.erb +27 -0
  127. data/app/views/shared/_error_messages.html.erb +29 -0
  128. data/app/views/shared/_generic_user_alert.html.erb +4 -0
  129. data/app/views/status/current.html.erb +34 -0
  130. data/app/views/status/test.html.erb +50 -0
  131. data/app/views/system_config/index.html.erb +25 -0
  132. data/app/views/system_config/show_auth.html.erb +28 -0
  133. data/app/views/system_config/show_database.html.erb +36 -0
  134. data/app/views/system_config/show_email.html.erb +21 -0
  135. data/app/views/system_config/show_self_update.html.erb +13 -0
  136. data/app/views/system_update/index.html.erb +31 -0
  137. data/app/views/system_update/new.html.erb +2 -0
  138. data/app/views/test_access/allow_anon.html.erb +2 -0
  139. data/app/views/test_access/require_admin.html.erb +2 -0
  140. data/app/views/test_access/require_group_x.html.erb +2 -0
  141. data/app/views/test_access/require_user.html.erb +2 -0
  142. data/app/views/test_report/index.csv.csvrb +23 -0
  143. data/app/views/test_report/index.html.erb +6 -0
  144. data/app/views/test_report/index.pdf.prawn +50 -0
  145. data/app/views/test_report/index.xlsx.axlsx +28 -0
  146. data/app/views/users/_user.html.erb +57 -0
  147. data/app/views/users/_user_details.html.erb +15 -0
  148. data/app/views/users/_user_details_for_list.html.erb +1 -0
  149. data/app/views/users/_user_form.html.erb +13 -0
  150. data/app/views/users/disable_confirm.html.erb +19 -0
  151. data/app/views/users/edit.html.erb +15 -0
  152. data/app/views/users/index.html.erb +9 -0
  153. data/app/views/users/new.html.erb +10 -0
  154. data/app/views/users/show.html.erb +46 -0
  155. data/bin/rails +12 -0
  156. data/config/routes.rb +3 -0
  157. data/db/migrate/20160617172539_create_access_groups.rb +10 -0
  158. data/db/migrate/20160617172725_create_users.rb +26 -0
  159. data/db/migrate/20160617172833_create_user_login_histories.rb +12 -0
  160. data/db/migrate/20160622151720_create_access_group_user_members.rb +9 -0
  161. data/db/migrate/20160622151925_create_access_group_group_members.rb +9 -0
  162. data/db/migrate/20160701005706_create_ldap_access_groups.rb +11 -0
  163. data/db/migrate/20161108155029_create_system_configs.rb +11 -0
  164. data/db/seeds/barkest_core_01_create_users.rb +42 -0
  165. data/db/seeds.rb +53 -0
  166. data/lib/barkest_core/concerns/association_with_defaults.rb +55 -0
  167. data/lib/barkest_core/concerns/boolean_parser.rb +88 -0
  168. data/lib/barkest_core/concerns/date_parser.rb +181 -0
  169. data/lib/barkest_core/concerns/email_tester.rb +55 -0
  170. data/lib/barkest_core/concerns/encrypted_fields.rb +156 -0
  171. data/lib/barkest_core/concerns/named_model.rb +73 -0
  172. data/lib/barkest_core/concerns/number_parser.rb +145 -0
  173. data/lib/barkest_core/concerns/utc_conversion.rb +60 -0
  174. data/lib/barkest_core/engine.rb +105 -0
  175. data/lib/barkest_core/extensions/active_record_extensions.rb +120 -0
  176. data/lib/barkest_core/extensions/application_configuration_extensions.rb +38 -0
  177. data/lib/barkest_core/extensions/application_extensions.rb +50 -0
  178. data/lib/barkest_core/extensions/axlsx_extenstions.rb +157 -0
  179. data/lib/barkest_core/extensions/fixture_set_extensions.rb +107 -0
  180. data/lib/barkest_core/extensions/generator_extensions.rb +271 -0
  181. data/lib/barkest_core/extensions/main_app_extensions.rb +35 -0
  182. data/lib/barkest_core/extensions/prawn_document_extensions.rb +367 -0
  183. data/lib/barkest_core/extensions/prawn_table_extensions.rb +131 -0
  184. data/lib/barkest_core/extensions/router_extensions.rb +106 -0
  185. data/lib/barkest_core/extensions/simple_formatter_extensions.rb +66 -0
  186. data/lib/barkest_core/extensions/test_case_extensions.rb +348 -0
  187. data/lib/barkest_core/extensions/time_extensions.rb +164 -0
  188. data/lib/barkest_core/handlers/csv_handler.rb +30 -0
  189. data/lib/barkest_core/version.rb +3 -0
  190. data/lib/barkest_core.rb +324 -0
  191. data/lib/generators/barkest/install_generator.rb +102 -0
  192. data/lib/generators/barkest_core/actions/01_patch_application_controller.rb +55 -0
  193. data/lib/generators/barkest_core/actions/02_patch_application_mailer.rb +56 -0
  194. data/lib/generators/barkest_core/actions/03_patch_assets.rb +62 -0
  195. data/lib/generators/barkest_core/actions/04_patch_layouts.rb +36 -0
  196. data/lib/generators/barkest_core/actions/05_patch_routes.rb +93 -0
  197. data/lib/generators/barkest_core/actions/06_patch_seeds.rb +60 -0
  198. data/lib/generators/barkest_core/actions/07_copy_migrations.rb +51 -0
  199. data/lib/generators/barkest_core/actions/08_configure_database.rb +52 -0
  200. data/lib/generators/barkest_core/actions/09_configure_secrets.rb +29 -0
  201. data/lib/generators/barkest_core/actions/99_patch_gitignore.rb +57 -0
  202. data/lib/generators/barkest_core/install_generator.rb +17 -0
  203. data/test/barkest_core_test.rb +83 -0
  204. data/test/controllers/access_groups_controller_test.rb +53 -0
  205. data/test/controllers/contact_controller_test.rb +10 -0
  206. data/test/controllers/sessions_controller_test.rb +10 -0
  207. data/test/controllers/users_controller_test.rb +10 -0
  208. data/test/dummy/.gitignore +10 -0
  209. data/test/dummy/README.rdoc +28 -0
  210. data/test/dummy/Rakefile +6 -0
  211. data/test/dummy/app/assets/images/.keep +0 -0
  212. data/test/dummy/app/assets/javascripts/application.js +14 -0
  213. data/test/dummy/app/assets/stylesheets/application.css +16 -0
  214. data/test/dummy/app/controllers/application_controller.rb +5 -0
  215. data/test/dummy/app/controllers/concerns/.keep +0 -0
  216. data/test/dummy/app/helpers/application_helper.rb +2 -0
  217. data/test/dummy/app/mailers/.keep +0 -0
  218. data/test/dummy/app/mailers/application_mailer.rb +3 -0
  219. data/test/dummy/app/models/.keep +0 -0
  220. data/test/dummy/app/models/concerns/.keep +0 -0
  221. data/test/dummy/app/views/layouts/application.html.erb +1 -0
  222. data/test/dummy/app/views/layouts/mailer.html.erb +1 -0
  223. data/test/dummy/app/views/layouts/mailer.text.erb +1 -0
  224. data/test/dummy/app/views/system_config/show_fake.html.erb +3 -0
  225. data/test/dummy/bin/bundle +3 -0
  226. data/test/dummy/bin/rails +4 -0
  227. data/test/dummy/bin/rake +4 -0
  228. data/test/dummy/bin/setup +29 -0
  229. data/test/dummy/config/application.rb +27 -0
  230. data/test/dummy/config/boot.rb +5 -0
  231. data/test/dummy/config/environment.rb +5 -0
  232. data/test/dummy/config/environments/development.rb +47 -0
  233. data/test/dummy/config/environments/production.rb +79 -0
  234. data/test/dummy/config/environments/test.rb +44 -0
  235. data/test/dummy/config/initializers/assets.rb +11 -0
  236. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  237. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  238. data/test/dummy/config/initializers/db_updater_ext.rb +33 -0
  239. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  240. data/test/dummy/config/initializers/inflections.rb +16 -0
  241. data/test/dummy/config/initializers/mime_types.rb +4 -0
  242. data/test/dummy/config/initializers/session_store.rb +3 -0
  243. data/test/dummy/config/initializers/sys_config_ext.rb +12 -0
  244. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  245. data/test/dummy/config/locales/en.yml +23 -0
  246. data/test/dummy/config/routes.rb +60 -0
  247. data/test/dummy/config.ru +4 -0
  248. data/test/dummy/db/schema.rb +95 -0
  249. data/test/dummy/db/seeds/barkest_core_01_create_users.rb +42 -0
  250. data/test/dummy/db/seeds.rb +51 -0
  251. data/test/dummy/lib/assets/.keep +0 -0
  252. data/test/dummy/log/.keep +0 -0
  253. data/test/dummy/public/404.html +67 -0
  254. data/test/dummy/public/422.html +67 -0
  255. data/test/dummy/public/500.html +66 -0
  256. data/test/dummy/public/favicon.ico +0 -0
  257. data/test/dummy/sql/my_test_view.sql +3 -0
  258. data/test/fixtures/access_groups.yml +21 -0
  259. data/test/fixtures/users.yml +71 -0
  260. data/test/helpers/barkest_core/sessions_helper_test.rb +22 -0
  261. data/test/integration/access_group_mgmt_test.rb +33 -0
  262. data/test/integration/access_test.rb +24 -0
  263. data/test/integration/account_activations_access_test.rb +12 -0
  264. data/test/integration/contact_test.rb +98 -0
  265. data/test/integration/extra_partial_test.rb +41 -0
  266. data/test/integration/log_view_access_test.rb +12 -0
  267. data/test/integration/password_resets_test.rb +101 -0
  268. data/test/integration/reports_test.rb +53 -0
  269. data/test/integration/status_access_test.rb +27 -0
  270. data/test/integration/system_config_access_test.rb +24 -0
  271. data/test/integration/system_update_access_test.rb +19 -0
  272. data/test/integration/users_access_test.rb +34 -0
  273. data/test/integration/users_edit_test.rb +178 -0
  274. data/test/integration/users_index_test.rb +62 -0
  275. data/test/integration/users_login_test.rb +67 -0
  276. data/test/integration/users_signup_test.rb +54 -0
  277. data/test/mailers/.keep +0 -0
  278. data/test/mailers/barkest_core/contact_form_test.rb +28 -0
  279. data/test/mailers/barkest_core/user_mailer_test.rb +43 -0
  280. data/test/mailers/previews/barkest_core/contact_form_preview.rb +17 -0
  281. data/test/mailers/previews/barkest_core/user_mailer_preview.rb +26 -0
  282. data/test/models/access_group_group_member_test.rb +28 -0
  283. data/test/models/access_group_test.rb +114 -0
  284. data/test/models/access_group_user_member_test.rb +28 -0
  285. data/test/models/barkest_core/auth_config_test.rb +57 -0
  286. data/test/models/barkest_core/bool_parser_test.rb +28 -0
  287. data/test/models/barkest_core/contact_message_test.rb +61 -0
  288. data/test/models/barkest_core/database_config_test.rb +33 -0
  289. data/test/models/barkest_core/date_parser_test.rb +110 -0
  290. data/test/models/barkest_core/email_config_test.rb +57 -0
  291. data/test/models/barkest_core/global_status_test.rb +50 -0
  292. data/test/models/barkest_core/ms_sql_db_updater_test.rb +115 -0
  293. data/test/models/barkest_core/ms_sql_definition_test.rb +102 -0
  294. data/test/models/barkest_core/ms_sql_function_test.rb +131 -0
  295. data/test/models/barkest_core/number_parser_test.rb +29 -0
  296. data/test/models/barkest_core/self_update_config_test.rb +29 -0
  297. data/test/models/barkest_core/user_alert_test.rb +19 -0
  298. data/test/models/barkest_core/user_manager_test.rb +34 -0
  299. data/test/models/barkest_core/work_path_test.rb +26 -0
  300. data/test/models/disable_user_test.rb +27 -0
  301. data/test/models/generic_time_test.rb +66 -0
  302. data/test/models/ldap_access_group_test.rb +31 -0
  303. data/test/models/pdf_table_builder_test.rb +6 -0
  304. data/test/models/system_config_test.rb +78 -0
  305. data/test/models/user_login_history_test.rb +37 -0
  306. data/test/models/user_test.rb +130 -0
  307. data/test/test_helper.rb +63 -0
  308. 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