barkest_core 1.5.3.0

Sign up to get free protection for your applications and to get access to all the features.
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,7 @@
1
+ module BarkestCore
2
+ ##
3
+ # A simple wrapper for a standard error to allow distinguishing authorization errors.
4
+ class AuthorizeFailure < StandardError
5
+
6
+ end
7
+ end
@@ -0,0 +1,37 @@
1
+ module BarkestCore
2
+ ##
3
+ # Defines the message generated by the generic contact form.
4
+ class ContactMessage
5
+ include ActiveModel::Model
6
+ include ActiveModel::Validations
7
+ include BarkestCore::EmailTester
8
+
9
+ attr_accessor :your_name, :your_email, :related_to, :subject, :body, :remote_ip
10
+
11
+ validates :your_name, presence: true
12
+ validates :your_email, presence: true, format: { with: VALID_EMAIL_REGEX }
13
+ validates :related_to, presence: true
14
+ validates :subject, presence: true, if: :need_subject?
15
+ validates :body, presence: true
16
+
17
+ ##
18
+ # Gets the full subject for the message.
19
+ def full_subject
20
+ return related_to if subject.blank?
21
+ "#{related_to}: #{subject}"
22
+ end
23
+
24
+ ##
25
+ # Sends the message.
26
+ def send_message
27
+ BarkestCore::ContactForm.contact(self).deliver_now
28
+ end
29
+
30
+ private
31
+
32
+ def need_subject?
33
+ related_to.to_s.downcase == 'other'
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,223 @@
1
+ module BarkestCore
2
+
3
+ ##
4
+ # Defines a database configuration for a database other than the core database.
5
+ #
6
+ # The core database must be configurared in +database.yml+ since it defines the SystemConfig.
7
+ #
8
+ # Other databases (say for a 3rd party database) can easily be defined using SystemConfig
9
+ # and this class.
10
+ class DatabaseConfig
11
+ include ActiveModel::Model
12
+ include ActiveModel::Validations
13
+
14
+ attr_accessor :name, :adapter, :encoding, :reconnect, :database, :pool, :username, :password, :timeout, :host, :port
15
+ attr_accessor :extra_1_name, :extra_1_label, :extra_1_type
16
+ attr_accessor :extra_2_name, :extra_2_label, :extra_2_type
17
+ attr_accessor :extra_3_name, :extra_3_label, :extra_3_type
18
+ attr_accessor :extra_4_name, :extra_4_label, :extra_4_type
19
+ attr_accessor :extra_5_name, :extra_5_label, :extra_5_type
20
+ attr_writer :extra_1_value, :extra_2_value, :extra_3_value, :extra_4_value, :extra_5_value
21
+ attr_accessor :update_username, :update_password
22
+
23
+ VALID_ADAPTERS = %w(sqlite3 mysql2 postgresql sqlserver)
24
+
25
+ validates :adapter, inclusion: { in: VALID_ADAPTERS }
26
+ validates :name, presence: true, length: { maximum: 128 }
27
+ validates :database, presence: true
28
+ validates :pool, presence: true
29
+ validates :timeout, presence: true
30
+
31
+ EXTRA_REGEX = /^extra_(?<KEY>\d+)_(?<VAR>name|label|type|value)$/
32
+ VALID_EXTRA_KEY = (1..5)
33
+ private_constant :EXTRA_REGEX, :VALID_EXTRA_KEY
34
+
35
+ ##
36
+ # Initializes the configuration.
37
+ #
38
+ # Define the parameters as hash values. A string without a key will be used to set the name.
39
+ def initialize(*args)
40
+ @extra = []
41
+ args.each do |arg|
42
+ if arg.is_a?(String)
43
+ self.name = arg
44
+ elsif arg.is_a?(Hash)
45
+ arg.each do |k,v|
46
+ if respond_to?(:"#{k}?")
47
+ send :"#{k}=", ((v === true || v === '1') ? '1' : '0')
48
+ elsif respond_to?(:"#{k}")
49
+ send :"#{k}=", v.to_s
50
+ elsif (extra = EXTRA_REGEX.match(k.to_s))
51
+ key = extra['KEY'].to_i
52
+ if VALID_EXTRA_KEY.include?(key)
53
+ send :"extra_#{key}_#{extra['VAR']}=", v.to_s
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ # :nodoc:
62
+ def method_missing(m,*a,&b)
63
+ m = m.to_s
64
+
65
+ if (key = EXTRA_REGEX.match(m))
66
+ if key['VAR'] == 'value'
67
+ key = key['KEY'].to_i
68
+ if VALID_EXTRA_KEY.include?(key)
69
+ ivar = :"@#{m}"
70
+ val = instance_variable_defined?(ivar) ? instance_variable_get(ivar) : nil
71
+ tp = send("extra_#{key}_type")
72
+ if tp == 'boolean'
73
+ val = ((val === true) || (val == '1')) ? '1' : '0'
74
+ end
75
+ return val
76
+ end
77
+ end
78
+ end
79
+
80
+ super m, *a, &b
81
+ end
82
+
83
+ ##
84
+ # Is the database configured to reconnect?
85
+ def reconnect?
86
+ reconnect.to_s.to_i != 0
87
+ end
88
+
89
+ ##
90
+ # Gets the name for an extra value.
91
+ def extra_name(index)
92
+ return nil if index < 1 || index > 5
93
+ send "extra_#{index}_name"
94
+ end
95
+
96
+ ##
97
+ # Gets the label for an extra value.
98
+ def extra_label(index)
99
+ return nil if index < 1 || index > 5
100
+ txt = send("extra_#{index}_label")
101
+ txt = extra_name(index).to_s.humanize.capitalize if txt.blank?
102
+ txt
103
+ end
104
+
105
+ ##
106
+ # Gets the type for an extra value.
107
+ def extra_type(index)
108
+ return nil if index < 1 || index > 5
109
+ send "extra_#{index}_type"
110
+ end
111
+
112
+ ##
113
+ # Gets the field type for an extra value.
114
+ def extra_field_type(index)
115
+ t = extra_type(index).to_s
116
+ case t
117
+ when 'password'
118
+ 'password'
119
+ when 'integer', 'float'
120
+ 'number'
121
+ when 'boolean'
122
+ 'checkbox'
123
+ else
124
+ if t.downcase.index('in:')
125
+ 'select'
126
+ else
127
+ 'text'
128
+ end
129
+ end
130
+ end
131
+
132
+ ##
133
+ # Gets the options for a select field.
134
+ def extra_field_options(index)
135
+ if extra_field_type(index) == 'select'
136
+ eval extra_type(index).partition(':')[2]
137
+ else
138
+ nil
139
+ end
140
+ end
141
+
142
+ ##
143
+ # Gets an extra value.
144
+ def extra_value(index, convert = false)
145
+ return nil if index < 1 || index > 5
146
+ val = send "extra_#{index}_value"
147
+ if convert
148
+ case extra_type(index)
149
+ when 'boolean'
150
+ BarkestCore::BooleanParser.parse_for_boolean_column(val)
151
+ when 'integer'
152
+ BarkestCore::NumberParser.parse_for_int_column(val)
153
+ when 'float'
154
+ BarkestCore::NumberParser.parse_for_float_column(val)
155
+ else
156
+ val.to_s
157
+ end
158
+ end
159
+ end
160
+
161
+
162
+ ##
163
+ # Converts this configuration into a hash.
164
+ def to_h(convert_extra = true)
165
+ ret = {
166
+ adapter: adapter.to_s,
167
+ database: database.to_s,
168
+ pool: pool.to_s.to_i,
169
+ timeout: timeout.to_s.to_i,
170
+ reconnect: reconnect?,
171
+ encoding: encoding ? encoding.to_s : nil,
172
+ host: host.blank? ? nil : host.to_s,
173
+ port: port.blank? ? nil : port.to_s.to_i,
174
+ username: username.blank? ? nil : username.to_s,
175
+ password: password.blank? ? nil : password.to_s,
176
+ update_username: update_username.blank? ? nil : update_username.to_s,
177
+ update_password: update_password.blank? ? nil : update_password.to_s,
178
+ }
179
+ VALID_EXTRA_KEY.each do |idx|
180
+ if convert_extra
181
+ unless extra_name(idx).blank?
182
+ ret[extra_name(idx).to_sym] = extra_value(idx, true)
183
+ end
184
+ else
185
+ ret[:"extra_#{idx}_name"] = send(:"extra_#{idx}_name")
186
+ ret[:"extra_#{idx}_label"] = send(:"extra_#{idx}_label")
187
+ ret[:"extra_#{idx}_type"] = send(:"extra_#{idx}_type")
188
+ ret[:"extra_#{idx}_value"] = send(:"extra_#{idx}_value")
189
+ end
190
+ end
191
+ ret
192
+ end
193
+
194
+ ##
195
+ # Saves this configuration (encrypted) to SystemConfig.
196
+ def save
197
+ SystemConfig.set name, to_h(false), true
198
+ end
199
+
200
+ ##
201
+ # Loads the configuration for the specified database from SystemConfig.
202
+ def DatabaseConfig.load(name)
203
+ DatabaseConfig.new(name, SystemConfig.get(name))
204
+ end
205
+
206
+ ##
207
+ # Gets a list of the registered databases for enumeration.
208
+ def DatabaseConfig.registered
209
+ @registered ||= []
210
+ end
211
+
212
+ ##
213
+ # Registers a database for enumeration.
214
+ def DatabaseConfig.register(db_id)
215
+ db_id = db_id.to_s.downcase
216
+ unless db_id.blank?
217
+ registered << db_id unless registered.include?(db_id)
218
+ end
219
+ nil
220
+ end
221
+
222
+ end
223
+ end
@@ -0,0 +1,21 @@
1
+ # this shouldn't be necessary, but engines seem to have a few weak spots.
2
+ require 'will_paginate/active_record'
3
+
4
+ module BarkestCore
5
+
6
+ ##
7
+ # This class serves as a base class for other models.
8
+ #
9
+ # This way we can guarantee that all of our models can use an explicit configuration
10
+ # when desirable.
11
+ class DbTable < ActiveRecord::Base
12
+ self.abstract_class = true
13
+
14
+ # Ensure that we only establish a new connection if needed.
15
+ unless BarkestCore.db_config.symbolize_keys == ActiveRecord::Base.connection_config.symbolize_keys
16
+ establish_connection BarkestCore.db_config
17
+ end
18
+
19
+ end
20
+
21
+ end
@@ -0,0 +1,132 @@
1
+ module BarkestCore
2
+ ##
3
+ # Defines the email configuration for the system.
4
+ class EmailConfig
5
+ include ActiveModel::Model
6
+ include ActiveModel::Validations
7
+
8
+ attr_accessor :config_mode, :default_sender, :default_recipient, :default_hostname
9
+ attr_accessor :address, :port, :authentication, :ssl, :enable_starttls_auto, :user_name, :password
10
+
11
+ VALID_CONFIG_MODES = %w(none smtp test)
12
+ VALID_AUTH_MODES = %w(none plain login cram_md5 ntlm)
13
+
14
+ validates :config_mode, inclusion: { in: VALID_CONFIG_MODES }
15
+ validates :default_sender, presence: true
16
+ validates :default_recipient, presence: true
17
+ validates :default_hostname, presence: true
18
+
19
+ with_options if: :smtp?, presence: true do
20
+ validates :address
21
+ validates :port
22
+ validates :authentication, inclusion: { in: VALID_AUTH_MODES }
23
+ end
24
+
25
+ validate :smtp_validate, if: :smtp?
26
+
27
+ ##
28
+ # Initializes the configuration.
29
+ def initialize(*args)
30
+ args.each do |arg|
31
+ if arg.is_a?(Hash)
32
+ arg.each do |k,v|
33
+ if respond_to?(:"#{k}?")
34
+ send :"#{k}=", ((v === true || v === '1') ? '1' : '0')
35
+ elsif respond_to?(k)
36
+ send :"#{k}=", v.to_s
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ ##
44
+ # Is SMTP enabled?
45
+ def smtp?
46
+ config_mode.to_s.downcase == 'smtp'
47
+ end
48
+
49
+ ##
50
+ # Is SSL enabled for SMTP?
51
+ def ssl?
52
+ ssl.to_s.to_i != 0
53
+ end
54
+
55
+ ##
56
+ # Is STARTTLS enabled for SMTP?
57
+ def enable_starttls_auto?
58
+ enable_starttls_auto.to_s.to_i != 0
59
+ end
60
+
61
+ ##
62
+ # Converts this configuration into a hash.
63
+ def to_h
64
+ {
65
+ config_mode: config_mode.to_s.to_sym,
66
+ default_sender: default_sender.to_s,
67
+ default_recipient: default_recipient.to_s,
68
+ default_hostname: default_hostname.to_s,
69
+ address: address.to_s,
70
+ port: port.to_s.to_i,
71
+ authentication: authentication.to_s.to_sym,
72
+ ssl: ssl?,
73
+ enable_starttls_auto: enable_starttls_auto?,
74
+ user_name: user_name.to_s,
75
+ password: password.to_s,
76
+ }
77
+ end
78
+
79
+ ##
80
+ # Saves this configuration (encrypted) to SystemConfig.
81
+ def save
82
+ SystemConfig.set :email, to_h, true
83
+ end
84
+
85
+ ##
86
+ # Loads the configuration from SystemConfig.
87
+ def EmailConfig.load
88
+ EmailConfig.new SystemConfig.get(:email)
89
+ end
90
+
91
+ private
92
+
93
+ def smtp_validate
94
+ return nil if Rails.env.test?
95
+
96
+ # no need to test unless we are configured for SMTP.
97
+ return nil unless smtp?
98
+
99
+ # already failed if these are missing.
100
+ return nil if address.blank? || port.blank? || authentication.blank?
101
+
102
+ # or these
103
+ return nil if default_sender.blank? || default_recipient.blank? || default_hostname.blank?
104
+
105
+ # send a test message.
106
+ begin
107
+ client = Net::SMTP.new(address, port)
108
+ begin
109
+ client.enable_ssl if ssl?
110
+ client.start(default_hostname, user_name, password, authentication.to_sym)
111
+ msgstr = <<-MESSAGE
112
+ From: #{default_sender}
113
+ To: #{default_recipient}
114
+ Subject: Test message
115
+
116
+ This is a test message sent with the new #{Rails.env} configuration for #{default_hostname}.
117
+ This message was sent at #{Time.zone.now}.
118
+ MESSAGE
119
+ client.send_message(msgstr, default_sender, default_recipient)
120
+ ensure
121
+ client.finish rescue nil
122
+ end
123
+
124
+ nil
125
+ rescue =>e
126
+ errors.add :base, "Failed to send test message. " + e.message
127
+ end
128
+ end
129
+
130
+
131
+ end
132
+ end
@@ -0,0 +1,267 @@
1
+ module BarkestCore
2
+ ##
3
+ # An interface to a global status/lock file.
4
+ #
5
+ # The global status/lock file is a simple two line file.
6
+ # The first line is the global status message.
7
+ # The second line is the global status progress.
8
+ #
9
+ # The real magic comes when we take advantage of exclusive locks.
10
+ # The process that will be managing the status takes an exclusive lock on the status/lock file.
11
+ # This prevents any other process from taking an exclusive lock.
12
+ # It does not prevent other processes from reading from the file.
13
+ #
14
+ # So the main process can update the file at any time, until it releases the lock.
15
+ # The other processes can read the file at any time, and test for the lock state to determine if the main
16
+ # process is still busy.
17
+ #
18
+ #
19
+ class GlobalStatus
20
+
21
+ ##
22
+ # The exception raised in the +lock_for+ method when +raise_on_failure+ is set.
23
+ FailureToLock = Class.new(StandardError)
24
+
25
+ ##
26
+ # Creates a new GlobalStatus object.
27
+ #
28
+ # If you specify a status file, then that file will be used for the locking and status reporting.
29
+ # Otherwise, the "global_lock" file will be used.
30
+ def initialize(status_file = nil)
31
+ @lock_handle = nil
32
+ @stat_handle = nil
33
+ @status_file_path = status_file
34
+ end
35
+
36
+ ##
37
+ # Gets the path to the global status file.
38
+ def status_file_path
39
+ @status_file_path ||= WorkPath.path_for('global_status')
40
+ end
41
+
42
+ ##
43
+ # Gets the path to the global lock file.
44
+ def lock_file_path
45
+ @lock_file_path ||= WorkPath.path_for('global_lock')
46
+ end
47
+
48
+ ##
49
+ # Determines if this instance has a lock on the status/lock file.
50
+ def have_lock?
51
+ !!@lock_handle
52
+ end
53
+
54
+ ##
55
+ # Determines if any process has a lock on the status/lock file.
56
+ def is_locked?
57
+ begin
58
+ return true if have_lock?
59
+ return true unless acquire_lock
60
+ ensure
61
+ release_lock
62
+ end
63
+ false
64
+ end
65
+
66
+ ##
67
+ # Gets the current status message from the status/lock file.
68
+ def get_message
69
+ get_status[:message]
70
+ end
71
+
72
+ ##
73
+ # Gets the current progress from the status/lock file.
74
+ def get_percentage
75
+ r = get_status[:percent]
76
+ r.blank? ? nil : r.to_i
77
+ end
78
+
79
+ ##
80
+ # Gets the current status from the status/lock file.
81
+ #
82
+ # Returns a hash with three elements:
83
+ #
84
+ # message::
85
+ # The current status message.
86
+ #
87
+ # percent::
88
+ # The current status progress.
89
+ #
90
+ # locked::
91
+ # The current lock state of the status/lock file. (true for locked, false for unlocked)
92
+ #
93
+ def get_status
94
+ r = {}
95
+ if have_lock?
96
+ @stat_handle.rewind
97
+ r[:message] = (@stat_handle.eof? ? 'The current process is busy.' : @stat_handle.readline.strip)
98
+ r[:percent] = (@stat_handle.eof? ? '' : @stat_handle.readline.strip)
99
+ r[:locked] = true
100
+ elsif is_locked?
101
+ if File.exist?(status_file_path)
102
+ begin
103
+ File.open(status_file_path, 'r') do |f|
104
+ r[:message] = (f.eof? ? 'The system is busy.' : f.readline.strip)
105
+ r[:percent] = (f.eof? ? '' : f.readline.strip)
106
+ end
107
+ rescue
108
+ r[:message] = 'The system appears busy.'
109
+ r[:percent] = ''
110
+ end
111
+ else
112
+ r[:message] = 'No status file.'
113
+ r[:percent] = ''
114
+ end
115
+ r[:locked] = true
116
+ else
117
+ r[:message] = 'The system is no longer busy.'
118
+ r[:percent] = '-'
119
+ r[:locked] = false
120
+ end
121
+ r
122
+ end
123
+
124
+ ##
125
+ # Sets the status message if this instance has a lock on the status/lock file.
126
+ #
127
+ # Returns true after successfully setting the message.
128
+ # Returns false if this instance does not currently hold the lock.
129
+ #
130
+ def set_message(value)
131
+ return false unless have_lock?
132
+ cur = get_status
133
+ set_status(value, cur[:percent])
134
+ end
135
+
136
+ ##
137
+ # Sets the status progress if this instance has a lock on the status/lock file.
138
+ #
139
+ # Returns true after successfully setting the progress.
140
+ # Returns false if this instance does not currently hold the lock.
141
+ #
142
+ def set_percentage(value)
143
+ return false unless have_lock?
144
+ cur = get_status
145
+ set_status(cur[:message], value)
146
+ end
147
+
148
+ ##
149
+ # Sets the status message and progress if this instance has a lock on the status/lock file.
150
+ #
151
+ # Returns true after successfully setting the status.
152
+ # Returns false if this instance does not currently hold the lock.
153
+ #
154
+ def set_status(message, percentage)
155
+ return false unless have_lock?
156
+ @stat_handle.rewind
157
+ @stat_handle.truncate 0
158
+ @stat_handle.write(message.to_s.strip + "\n")
159
+ @stat_handle.write(percentage.to_s.strip + "\n")
160
+ @stat_handle.flush
161
+ true
162
+ end
163
+
164
+ ##
165
+ # Releases the lock on the status/lock file if this instance holds the lock.
166
+ #
167
+ # Returns true.
168
+ #
169
+ def release_lock
170
+ return true unless @lock_handle
171
+ begin
172
+ set_message ''
173
+ @lock_handle.flock(File::LOCK_UN)
174
+ ensure
175
+ @stat_handle.close rescue nil
176
+ @lock_handle.close rescue nil
177
+ @stat_handle = @lock_handle = nil
178
+ end
179
+
180
+ true
181
+ end
182
+
183
+ ##
184
+ # Acquires the lock on the status/lock file.
185
+ #
186
+ # Returns true on success or if this instance already holds the lock.
187
+ # Returns false if another process holds the lock.
188
+ #
189
+ def acquire_lock
190
+ return true if @lock_handle
191
+ begin
192
+ @lock_handle = File.open(lock_file_path, File::RDWR | File::CREAT)
193
+ raise StandardError.new('Already locked') unless @lock_handle.flock(File::LOCK_EX | File::LOCK_NB)
194
+ @lock_handle.rewind
195
+ @lock_handle.truncate 0
196
+ @stat_handle = File.open(status_file_path, File::RDWR | File::CREAT)
197
+ raise StandardError.new('Failed to open status') unless @stat_handle
198
+ @stat_handle.rewind
199
+ @stat_handle.truncate 0
200
+ rescue
201
+ if @stat_handle
202
+ @stat_handle.close rescue nil
203
+ end
204
+ if @lock_handle
205
+ @lock_handle.flock(File::LOCK_UN) rescue nil
206
+ @lock_handle.close rescue nil
207
+ end
208
+ @stat_handle = nil
209
+ @lock_handle = nil
210
+ end
211
+ !!@lock_handle
212
+ end
213
+
214
+ ##
215
+ # Determines if any process currently holds the lock on the status/lock file.
216
+ #
217
+ # Returns true if the file is locked, otherwise returns false.
218
+ #
219
+ def self.locked?
220
+ global_instance.is_locked?
221
+ end
222
+
223
+ ##
224
+ # Gets the current status from the status/lock file.
225
+ #
226
+ # See #get_status for a description of the returned hash.
227
+ #
228
+ def self.current
229
+ global_instance.get_status
230
+ end
231
+
232
+ ##
233
+ # Runs the provided block with a lock on the status/lock file.
234
+ #
235
+ # If a lock can be acquired, a GlobalStatus object is yielded to the block.
236
+ # The lock will automatically be released when the block exits.
237
+ #
238
+ # If a lock cannot be acquire, then false is yielded to the block.
239
+ # The block needs to test for this case to ensure that the appropriate
240
+ # error handling is performed.
241
+ #
242
+ # The only time that the block is not called is if +raise_on_failure+ is set,
243
+ # in which case an exception is raised instead of yielding to the block.
244
+ #
245
+ def self.lock_for(raise_on_failure = false, &block)
246
+ return unless block_given?
247
+ status = GlobalStatus.new
248
+ if status.acquire_lock
249
+ begin
250
+ yield status
251
+ ensure
252
+ status.release_lock
253
+ end
254
+ else
255
+ raise BarkestCore::GlobalStatus::FailureToLock.new if raise_on_failure
256
+ yield false
257
+ end
258
+ end
259
+
260
+ private
261
+
262
+ def self.global_instance
263
+ @global_instance ||= GlobalStatus.new
264
+ end
265
+
266
+ end
267
+ end