incline 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (303) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +13 -0
  3. data/Gemfile +17 -0
  4. data/Gemfile.lock +186 -0
  5. data/MIT-LICENSE +20 -0
  6. data/README.rdoc +208 -0
  7. data/Rakefile +37 -0
  8. data/app/assets/fonts/incline/.keep +0 -0
  9. data/app/assets/images/incline/.keep +0 -0
  10. data/app/assets/images/incline/barcode-B.svg +181 -0
  11. data/app/assets/javascripts/incline/activate_classed_items.js +11 -0
  12. data/app/assets/javascripts/incline/application.js +30 -0
  13. data/app/assets/javascripts/incline/bootstrap-datepicker.js +1800 -0
  14. data/app/assets/javascripts/incline/datatables.js +22193 -0
  15. data/app/assets/javascripts/incline/escapeHtml.js +10 -0
  16. data/app/assets/javascripts/incline/inline_actions.js +479 -0
  17. data/app/assets/javascripts/incline/jquery.doubleScroll.js +112 -0
  18. data/app/assets/javascripts/incline/jquery.number.js +764 -0
  19. data/app/assets/javascripts/incline/regexMask.js +27 -0
  20. data/app/assets/javascripts/incline/select2/i18n/en.js +3 -0
  21. data/app/assets/javascripts/incline/select2/select2.full.js +6436 -0
  22. data/app/assets/stylesheets/incline/application.css +18 -0
  23. data/app/assets/stylesheets/incline/bootstrap-theme.min.css +5 -0
  24. data/app/assets/stylesheets/incline/custom.scss +279 -0
  25. data/app/assets/stylesheets/incline/datatables.css +494 -0
  26. data/app/assets/stylesheets/incline/datepicker3.css +790 -0
  27. data/app/assets/stylesheets/incline/select2.css +484 -0
  28. data/app/controllers/incline/access_groups_controller.rb +127 -0
  29. data/app/controllers/incline/access_test_controller.rb +30 -0
  30. data/app/controllers/incline/account_activations_controller.rb +28 -0
  31. data/app/controllers/incline/application_controller.rb +11 -0
  32. data/app/controllers/incline/contact_controller.rb +34 -0
  33. data/app/controllers/incline/password_resets_controller.rb +113 -0
  34. data/app/controllers/incline/security_controller.rb +100 -0
  35. data/app/controllers/incline/sessions_controller.rb +50 -0
  36. data/app/controllers/incline/users_controller.rb +304 -0
  37. data/app/controllers/incline/welcome_controller.rb +19 -0
  38. data/app/helpers/incline/.keep +0 -0
  39. data/app/mailers/incline/application_mailer_base.rb +11 -0
  40. data/app/mailers/incline/contact_form.rb +19 -0
  41. data/app/mailers/incline/user_mailer.rb +45 -0
  42. data/app/models/incline/access_group.rb +121 -0
  43. data/app/models/incline/access_group_group_member.rb +12 -0
  44. data/app/models/incline/access_group_user_member.rb +10 -0
  45. data/app/models/incline/action_group.rb +12 -0
  46. data/app/models/incline/action_security.rb +222 -0
  47. data/app/models/incline/contact_message.rb +37 -0
  48. data/app/models/incline/disable_info.rb +20 -0
  49. data/app/models/incline/password_reset.rb +14 -0
  50. data/app/models/incline/password_reset_request.rb +14 -0
  51. data/app/models/incline/user.rb +437 -0
  52. data/app/models/incline/user_login_history.rb +30 -0
  53. data/app/views/incline/access_groups/_details.json.jbuilder +10 -0
  54. data/app/views/incline/access_groups/_form.html.erb +19 -0
  55. data/app/views/incline/access_groups/_list.html.erb +60 -0
  56. data/app/views/incline/access_groups/_messages.json.jbuilder +6 -0
  57. data/app/views/incline/access_groups/edit.html.erb +2 -0
  58. data/app/views/incline/access_groups/index.html.erb +6 -0
  59. data/app/views/incline/access_groups/index.json.jbuilder +16 -0
  60. data/app/views/incline/access_groups/new.html.erb +2 -0
  61. data/app/views/incline/access_groups/show.html.erb +9 -0
  62. data/app/views/incline/access_groups/show.json.jbuilder +11 -0
  63. data/app/views/incline/contact/new.html.erb +22 -0
  64. data/app/views/incline/contact_form/contact.html.erb +16 -0
  65. data/app/views/incline/contact_form/contact.text.erb +13 -0
  66. data/app/views/incline/password_resets/edit.html.erb +16 -0
  67. data/app/views/incline/password_resets/new.html.erb +12 -0
  68. data/app/views/incline/security/_details.json.jbuilder +7 -0
  69. data/app/views/incline/security/_form.html.erb +20 -0
  70. data/app/views/incline/security/_list.html.erb +89 -0
  71. data/app/views/incline/security/_messages.json.jbuilder +6 -0
  72. data/app/views/incline/security/edit.html.erb +2 -0
  73. data/app/views/incline/security/index.html.erb +6 -0
  74. data/app/views/incline/security/index.json.jbuilder +16 -0
  75. data/app/views/incline/security/show.html.erb +31 -0
  76. data/app/views/incline/security/show.json.jbuilder +11 -0
  77. data/app/views/incline/sessions/new.html.erb +26 -0
  78. data/app/views/incline/user_mailer/account_activation.html.erb +7 -0
  79. data/app/views/incline/user_mailer/account_activation.text.erb +6 -0
  80. data/app/views/incline/user_mailer/invalid_password_reset.html.erb +3 -0
  81. data/app/views/incline/user_mailer/invalid_password_reset.text.erb +5 -0
  82. data/app/views/incline/user_mailer/password_reset.html.erb +8 -0
  83. data/app/views/incline/user_mailer/password_reset.text.erb +7 -0
  84. data/app/views/incline/users/_details.json.jbuilder +32 -0
  85. data/app/views/incline/users/_form.html.erb +21 -0
  86. data/app/views/incline/users/_list.html.erb +102 -0
  87. data/app/views/incline/users/_messages.json.jbuilder +6 -0
  88. data/app/views/incline/users/disable_confirm.html.erb +19 -0
  89. data/app/views/incline/users/edit.html.erb +5 -0
  90. data/app/views/incline/users/index.html.erb +6 -0
  91. data/app/views/incline/users/index.json.jbuilder +16 -0
  92. data/app/views/incline/users/new.html.erb +5 -0
  93. data/app/views/incline/users/show.html.erb +12 -0
  94. data/app/views/incline/users/show.json.jbuilder +11 -0
  95. data/app/views/incline/welcome/home.html.erb +5 -0
  96. data/app/views/layouts/application.html.erb +1 -0
  97. data/app/views/layouts/incline/_account_menu.html.erb +18 -0
  98. data/app/views/layouts/incline/_app_menu_anon.html.erb +1 -0
  99. data/app/views/layouts/incline/_app_menu_authenticated.html.erb +1 -0
  100. data/app/views/layouts/incline/_footer.html.erb +13 -0
  101. data/app/views/layouts/incline/_header.html.erb +21 -0
  102. data/app/views/layouts/incline/_html_mailer.html.erb +5 -0
  103. data/app/views/layouts/incline/_incline_app.html.erb +25 -0
  104. data/app/views/layouts/incline/_messages.html.erb +3 -0
  105. data/app/views/layouts/incline/_shim.html.erb +3 -0
  106. data/app/views/layouts/incline/_text_mailer.text.erb +1 -0
  107. data/app/views/layouts/incline/application.html.erb +1 -0
  108. data/app/views/layouts/mailer.html.erb +2 -0
  109. data/app/views/layouts/mailer.text.erb +2 -0
  110. data/bin/rails +12 -0
  111. data/bin/test_scaffold.sh +10 -0
  112. data/config/routes.rb +61 -0
  113. data/db/migrate/20170511230126_create_incline_users.rb +26 -0
  114. data/db/migrate/20170515003052_create_incline_access_groups.rb +10 -0
  115. data/db/migrate/20170515003221_create_incline_user_login_histories.rb +12 -0
  116. data/db/migrate/20170515150908_create_incline_access_group_user_members.rb +11 -0
  117. data/db/migrate/20170515151058_create_incline_access_group_group_members.rb +11 -0
  118. data/db/migrate/20170517193432_add_comments_to_incline_user.rb +5 -0
  119. data/db/migrate/20170622132700_create_incline_action_securities.rb +16 -0
  120. data/db/migrate/20170622172712_create_incline_action_groups.rb +11 -0
  121. data/db/migrate/20170622195742_add_non_standard_to_action_security.rb +5 -0
  122. data/db/migrate/20170622230422_add_visible_to_action_security.rb +5 -0
  123. data/db/seeds.rb +81 -0
  124. data/exe/new_incline_app +42 -0
  125. data/lib/generators/incline/install_generator.rb +259 -0
  126. data/lib/generators/incline/templates/_app_menu_anon.html.erb +1 -0
  127. data/lib/generators/incline/templates/_app_menu_authenticated.html.erb +1 -0
  128. data/lib/generators/incline/templates/incline_application.css +17 -0
  129. data/lib/generators/incline/templates/incline_application.html.erb +1 -0
  130. data/lib/generators/incline/templates/incline_application.js +12 -0
  131. data/lib/generators/incline/templates/incline_database.yml +25 -0
  132. data/lib/generators/incline/templates/incline_email.yml +20 -0
  133. data/lib/generators/incline/templates/incline_mailer.html.erb +2 -0
  134. data/lib/generators/incline/templates/incline_mailer.text.erb +2 -0
  135. data/lib/generators/incline/templates/incline_users.yml +64 -0
  136. data/lib/generators/incline/templates/incline_version.rb +3 -0
  137. data/lib/incline/auth_engine_base.rb +52 -0
  138. data/lib/incline/data_tables_request.rb +336 -0
  139. data/lib/incline/date_time_formats.rb +6 -0
  140. data/lib/incline/engine.rb +212 -0
  141. data/lib/incline/errors.rb +15 -0
  142. data/lib/incline/extensions/action_controller_base.rb +526 -0
  143. data/lib/incline/extensions/action_mailer_base.rb +66 -0
  144. data/lib/incline/extensions/action_view_base.rb +489 -0
  145. data/lib/incline/extensions/active_record_base.rb +308 -0
  146. data/lib/incline/extensions/application.rb +137 -0
  147. data/lib/incline/extensions/application_configuration.rb +50 -0
  148. data/lib/incline/extensions/connection_adapter.rb +55 -0
  149. data/lib/incline/extensions/date_time_value.rb +123 -0
  150. data/lib/incline/extensions/date_value.rb +77 -0
  151. data/lib/incline/extensions/decimal_value.rb +55 -0
  152. data/lib/incline/extensions/erb_scaffold_generator.rb +31 -0
  153. data/lib/incline/extensions/float_value.rb +59 -0
  154. data/lib/incline/extensions/form_builder.rb +617 -0
  155. data/lib/incline/extensions/integer_value.rb +54 -0
  156. data/lib/incline/extensions/jbuilder_generator.rb +38 -0
  157. data/lib/incline/extensions/jbuilder_template.rb +39 -0
  158. data/lib/incline/extensions/main_app.rb +40 -0
  159. data/lib/incline/extensions/numeric.rb +63 -0
  160. data/lib/incline/extensions/object.rb +31 -0
  161. data/lib/incline/extensions/resource_route_generator.rb +53 -0
  162. data/lib/incline/extensions/session.rb +113 -0
  163. data/lib/incline/extensions/string.rb +50 -0
  164. data/lib/incline/extensions/test_case.rb +764 -0
  165. data/lib/incline/extensions/time_zone_converter.rb +40 -0
  166. data/lib/incline/global_status.rb +236 -0
  167. data/lib/incline/helpers/route_hash_formatter.rb +46 -0
  168. data/lib/incline/json_log_formatter.rb +96 -0
  169. data/lib/incline/json_logger.rb +17 -0
  170. data/lib/incline/log.rb +153 -0
  171. data/lib/incline/number_formats.rb +17 -0
  172. data/lib/incline/recaptcha.rb +346 -0
  173. data/lib/incline/user_manager.rb +212 -0
  174. data/lib/incline/validators/email_validator.rb +45 -0
  175. data/lib/incline/validators/ip_address_validator.rb +32 -0
  176. data/lib/incline/validators/recaptcha_validator.rb +37 -0
  177. data/lib/incline/validators/safe_name_validator.rb +31 -0
  178. data/lib/incline/version.rb +3 -0
  179. data/lib/incline/work_path.rb +75 -0
  180. data/lib/incline.rb +197 -0
  181. data/lib/tasks/incline_tasks.rake +4 -0
  182. data/lib/templates/erb/scaffold/_form.html.erb +43 -0
  183. data/lib/templates/erb/scaffold/_list.html.erb +81 -0
  184. data/lib/templates/erb/scaffold/edit.html.erb +1 -0
  185. data/lib/templates/erb/scaffold/index.html.erb +6 -0
  186. data/lib/templates/erb/scaffold/new.html.erb +1 -0
  187. data/lib/templates/erb/scaffold/show.html.erb +34 -0
  188. data/lib/templates/jbuilder/scaffold/_details.json.jbuilder +20 -0
  189. data/lib/templates/jbuilder/scaffold/index.json.jbuilder +16 -0
  190. data/lib/templates/jbuilder/scaffold/show.json.jbuilder +16 -0
  191. data/lib/templates/rails/scaffold_controller/controller.rb +128 -0
  192. data/test/controllers/incline/access_groups_controller_test.rb +65 -0
  193. data/test/controllers/incline/access_test_controller_test.rb +53 -0
  194. data/test/controllers/incline/contact_controller_test.rb +32 -0
  195. data/test/controllers/incline/security_controller_test.rb +39 -0
  196. data/test/controllers/incline/welcome_controller_test.rb +16 -0
  197. data/test/dummy/README.rdoc +28 -0
  198. data/test/dummy/Rakefile +6 -0
  199. data/test/dummy/app/assets/images/.keep +0 -0
  200. data/test/dummy/app/assets/javascripts/application.js +12 -0
  201. data/test/dummy/app/assets/stylesheets/application.css +17 -0
  202. data/test/dummy/app/controllers/application_controller.rb +5 -0
  203. data/test/dummy/app/controllers/concerns/.keep +0 -0
  204. data/test/dummy/app/helpers/application_helper.rb +2 -0
  205. data/test/dummy/app/mailers/.keep +0 -0
  206. data/test/dummy/app/models/.keep +0 -0
  207. data/test/dummy/app/models/concerns/.keep +0 -0
  208. data/test/dummy/app/views/layouts/application.html.erb +1 -0
  209. data/test/dummy/app/views/layouts/incline/_app_menu_anon.html.erb +1 -0
  210. data/test/dummy/app/views/layouts/incline/_app_menu_authenticated.html.erb +1 -0
  211. data/test/dummy/app/views/layouts/mailer.html.erb +2 -0
  212. data/test/dummy/app/views/layouts/mailer.text.erb +2 -0
  213. data/test/dummy/bin/bundle +3 -0
  214. data/test/dummy/bin/rails +4 -0
  215. data/test/dummy/bin/rake +4 -0
  216. data/test/dummy/bin/setup +29 -0
  217. data/test/dummy/config/application.rb +38 -0
  218. data/test/dummy/config/boot.rb +5 -0
  219. data/test/dummy/config/database.yml +34 -0
  220. data/test/dummy/config/email.yml +24 -0
  221. data/test/dummy/config/environment.rb +5 -0
  222. data/test/dummy/config/environments/development.rb +45 -0
  223. data/test/dummy/config/environments/production.rb +85 -0
  224. data/test/dummy/config/environments/test.rb +44 -0
  225. data/test/dummy/config/initializers/assets.rb +11 -0
  226. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  227. data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
  228. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  229. data/test/dummy/config/initializers/inflections.rb +16 -0
  230. data/test/dummy/config/initializers/mime_types.rb +4 -0
  231. data/test/dummy/config/initializers/session_store.rb +3 -0
  232. data/test/dummy/config/initializers/to_time_preserves_timezone.rb +10 -0
  233. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  234. data/test/dummy/config/locales/en.yml +23 -0
  235. data/test/dummy/config/routes.rb +6 -0
  236. data/test/dummy/config.ru +4 -0
  237. data/test/dummy/db/schema.rb +108 -0
  238. data/test/dummy/lib/assets/.keep +0 -0
  239. data/test/dummy/log/.keep +0 -0
  240. data/test/dummy/public/404.html +67 -0
  241. data/test/dummy/public/422.html +67 -0
  242. data/test/dummy/public/500.html +66 -0
  243. data/test/dummy/public/favicon.ico +0 -0
  244. data/test/extensions/action_controller_base_extensions_test.rb +21 -0
  245. data/test/extensions/action_mailer_base_extensions_test.rb +20 -0
  246. data/test/extensions/action_view_base_extensions_test.rb +267 -0
  247. data/test/extensions/active_record_extensions_test.rb +173 -0
  248. data/test/extensions/application_configuration_extensions_test.rb +46 -0
  249. data/test/extensions/application_extensions_test.rb +23 -0
  250. data/test/extensions/connection_adapter_extensions_test.rb +54 -0
  251. data/test/extensions/date_time_value_extensions_test.rb +104 -0
  252. data/test/extensions/date_value_extensions_test.rb +102 -0
  253. data/test/extensions/decimal_value_extensions_test.rb +85 -0
  254. data/test/extensions/erb_scaffold_generator_extensions_test.rb +17 -0
  255. data/test/extensions/float_value_extensions_test.rb +78 -0
  256. data/test/extensions/form_builder_extensions_test.rb +28 -0
  257. data/test/extensions/integer_value_extensions_test.rb +78 -0
  258. data/test/extensions/jbuilder_generator_extensions_test.rb +21 -0
  259. data/test/extensions/jbuilder_template_extensions_test.rb +47 -0
  260. data/test/extensions/main_app_extensions_test.rb +55 -0
  261. data/test/extensions/numeric_extensions_test.rb +76 -0
  262. data/test/extensions/object_extensions_test.rb +104 -0
  263. data/test/extensions/session_extensions_test.rb +69 -0
  264. data/test/extensions/string_extensions_test.rb +32 -0
  265. data/test/extensions/test_case_extensions_test.rb +538 -0
  266. data/test/extensions/time_zone_converter_extensions_test.rb +10 -0
  267. data/test/fixtures/incline/access_group_group_members.yml +1 -0
  268. data/test/fixtures/incline/access_group_user_members.yml +1 -0
  269. data/test/fixtures/incline/access_groups.yml +13 -0
  270. data/test/fixtures/incline/action_groups.yml +6 -0
  271. data/test/fixtures/incline/action_securities.yml +18 -0
  272. data/test/fixtures/incline/user_login_histories.yml +1 -0
  273. data/test/fixtures/incline/users.yml +64 -0
  274. data/test/incline_test.rb +63 -0
  275. data/test/integration/incline/users_edit_test.rb +180 -0
  276. data/test/integration/incline/users_login_test.rb +105 -0
  277. data/test/integration/incline/users_signup_test.rb +147 -0
  278. data/test/integration/navigation_test.rb +11 -0
  279. data/test/lib/data_tables_request_test.rb +245 -0
  280. data/test/lib/date_time_formats_test.rb +111 -0
  281. data/test/lib/global_status_test.rb +89 -0
  282. data/test/lib/json_log_formatter_test.rb +43 -0
  283. data/test/lib/log_test.rb +36 -0
  284. data/test/lib/recaptcha_test.rb +75 -0
  285. data/test/lib/user_manager_test.rb +47 -0
  286. data/test/lib/work_path_test.rb +18 -0
  287. data/test/models/incline/access_group_group_member_test.rb +30 -0
  288. data/test/models/incline/access_group_test.rb +60 -0
  289. data/test/models/incline/access_group_user_member_test.rb +29 -0
  290. data/test/models/incline/action_group_test.rb +27 -0
  291. data/test/models/incline/action_security_test.rb +176 -0
  292. data/test/models/incline/contact_message_test.rb +66 -0
  293. data/test/models/incline/disable_info_test.rb +29 -0
  294. data/test/models/incline/password_reset_request_test.rb +35 -0
  295. data/test/models/incline/password_reset_test.rb +51 -0
  296. data/test/models/incline/user_login_history_test.rb +31 -0
  297. data/test/models/incline/user_test.rb +91 -0
  298. data/test/test_helper.rb +42 -0
  299. data/test/validators/email_validator_test.rb +102 -0
  300. data/test/validators/ip_address_validator_test.rb +107 -0
  301. data/test/validators/recaptcha_validator_test.rb +57 -0
  302. data/test/validators/safe_name_validator_test.rb +101 -0
  303. metadata +584 -0
@@ -0,0 +1,17 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any styles
10
+ * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
11
+ * file per style scope.
12
+ *
13
+ * This manifest inherits the default behavior of the Incline gem.
14
+ *
15
+ *= require incline/application
16
+ *= require_self
17
+ */
@@ -0,0 +1 @@
1
+ <%= render 'layouts/incline/incline_app' %>
@@ -0,0 +1,12 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
6
+ //
7
+ // This manifest inherits the default functionality from the Incline gem.
8
+ //
9
+ //= require incline/application
10
+
11
+ // Require any addition scripts you want/need, but you probably do not want to use "require_tree ." since that may
12
+ // lead to over-bloated JS code.
@@ -0,0 +1,25 @@
1
+ # SQLite version 3.x
2
+ # gem install sqlite3
3
+ #
4
+ # Ensure the SQLite 3 gem is defined in your Gemfile
5
+ # gem 'sqlite3'
6
+ #
7
+ default: &default
8
+ adapter: sqlite3
9
+ pool: 5
10
+ timeout: 5000
11
+
12
+ development:
13
+ <<: *default
14
+ database: db/development.sqlite3
15
+
16
+ # Warning: The database defined as "test" will be erased and
17
+ # re-generated from your development database when you run "rake".
18
+ # Do not set this db to the same as development or production.
19
+ test:
20
+ <<: *default
21
+ database: db/test.sqlite3
22
+
23
+ production:
24
+ <<: *default
25
+ database: db/production.sqlite3
@@ -0,0 +1,20 @@
1
+ default: &default
2
+ default_url: www.example.com
3
+ default_recipient: someone@example.com
4
+ sender: noreply@example.com
5
+ server: mail.example.com
6
+ auth: :plain
7
+ start_tls: false
8
+ ssl: true
9
+ port: 465
10
+ user: <%= (Rails.application.secrets['email'] || {})['user'] %>
11
+ password: <%= (Rails.application.secrets['email'] || {})['password'] %>
12
+
13
+ development:
14
+ <<: *default
15
+
16
+ test:
17
+ <<: *default
18
+
19
+ production:
20
+ <<: *default
@@ -0,0 +1,2 @@
1
+ <%= render 'layouts/incline/html_mailer' %>
2
+
@@ -0,0 +1,2 @@
1
+ <%= render 'layouts/incline/text_mailer' %>
2
+
@@ -0,0 +1,64 @@
1
+ # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
2
+
3
+ one:
4
+ name: George Jetson
5
+ email: george@example.com
6
+ activated: true
7
+ enabled: true
8
+ system_admin: false
9
+ password_digest: <%= Incline::User::digest 'Password123' %>
10
+ activated_at: <%= 20.days.ago %>
11
+ last_login_at: <%= 5.hours.ago %>
12
+ last_login_ip: 10.20.30.40
13
+
14
+ two:
15
+ name: Fred Flintstone
16
+ email: fred@example.com
17
+ activated: true
18
+ enabled: true
19
+ system_admin: false
20
+ password_digest: <%= Incline::User::digest 'Password123' %>
21
+ activated_at: <%= 9.days.ago %>
22
+ last_login_at: <%= 3.days.ago %>
23
+ last_login_ip: 1:2::3:4
24
+
25
+ admin:
26
+ name: Sys Admin
27
+ email: admin@example.com
28
+ activated: true
29
+ enabled: true
30
+ system_admin: true
31
+ password_digest: <%= Incline::User::digest 'Password123' %>
32
+ activated_at: <%= 30.days.ago %>
33
+
34
+ basic:
35
+ name: Basic User
36
+ email: basic@example.com
37
+ activated: true
38
+ enabled: true
39
+ system_admin: false
40
+ password_digest: <%= Incline::User::digest 'Password123' %>
41
+ activated_at: <%= 10.days.ago %>
42
+
43
+ disabled:
44
+ name: Bad User
45
+ email: bad@example.com
46
+ activated: true
47
+ enabled: false
48
+ system_admin: false
49
+ password_digest: <%= Incline::User::digest 'Password123' %>
50
+ disabled_by: admin@example.com
51
+ disabled_at: <%= 30.days.ago %>
52
+ activated_at: <%= 31.days.ago %>
53
+
54
+ recently_disabled:
55
+ name: Recent User
56
+ email: recent@example.com
57
+ activated: true
58
+ enabled: false
59
+ system_admin: false
60
+ password_digest: <%= Incline::User::digest 'Password123' %>
61
+ disabled_by: admin@example.com
62
+ disabled_at: <%= 1.days.ago %>
63
+ activated_at: <%= 3.days.ago %>
64
+
@@ -0,0 +1,3 @@
1
+ module <%= Rails.application.class.name.rpartition('::')[0] %>
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,52 @@
1
+
2
+ module Incline
3
+
4
+ ##
5
+ # Defines an auth engine.
6
+ class AuthEngineBase
7
+
8
+ ##
9
+ # The auth engine initializer should take a hash of parameters.
10
+ def initialize(options = {})
11
+ @options = options || {}
12
+ end
13
+
14
+ ##
15
+ # The authenticate method takes an email and password to authenticate a user and the client IP for logging purposes.
16
+ def authenticate(email, password, client_ip)
17
+ nil
18
+ end
19
+
20
+ protected
21
+
22
+ ##
23
+ # Logs a failure message for a user. The user can either be an Incline::User model or the email address used
24
+ # in the attempt.
25
+ def add_failure_to(user, message, client_ip) # :doc:
26
+ Incline::Log::info "LOGIN(#{user}) FAILURE FROM #{client_ip}: #{message}"
27
+ history_length = 2
28
+ unless user.is_a?(::Incline::User)
29
+ message = "[email: #{user}] #{message}"
30
+ user = User.anonymous
31
+ history_length = 6
32
+ end
33
+ purge_old_history_for user, history_length
34
+ user.login_histories.create(ip_address: client_ip, successful: false, message: message)
35
+ end
36
+
37
+ ##
38
+ # Logs a success message for a user.
39
+ def add_success_to(user, message, client_ip) # :doc:
40
+ Incline::Log::info "LOGIN(#{user}) SUCCESS FROM #{client_ip}: #{message}"
41
+ purge_old_history_for user
42
+ user.login_histories.create(ip_address: client_ip, successful: true, message: message)
43
+ end
44
+
45
+ private
46
+
47
+ def purge_old_history_for(user, max_months = 2)
48
+ user.login_histories.where('"incline_user_login_histories"."created_at" <= ?', Time.now - max_months.months).delete_all
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,336 @@
1
+ module Incline
2
+ ##
3
+ # Parses the parameters sent by a request from datatables.
4
+ class DataTablesRequest
5
+
6
+ ##
7
+ # Draw counter.
8
+ def draw
9
+ @config[:draw]
10
+ end
11
+
12
+ ##
13
+ # First record to return.
14
+ def start
15
+ @config[:start]
16
+ end
17
+
18
+ ##
19
+ # Number of records to return.
20
+ #
21
+ # Can be any positive value, or -1 to indicate that all records should be returned.
22
+ def length
23
+ @config[:length]
24
+ end
25
+
26
+ ##
27
+ # Text or regular expression to search with.
28
+ def search
29
+ @config[:search]
30
+ end
31
+
32
+ ##
33
+ # The columns requested.
34
+ def columns
35
+ @config[:columns]
36
+ end
37
+
38
+ ##
39
+ # The row ordering.
40
+ def ordering
41
+ @config[:order]
42
+ end
43
+
44
+ ##
45
+ # If we are searching for a specific ID, this is the ID to locate.
46
+ #
47
+ #
48
+ def locate_id
49
+ @config[:locate_id]
50
+ end
51
+
52
+ ##
53
+ # Initializes the data tables request parameters.
54
+ def initialize(params = {}, &block)
55
+ raise ArgumentError, 'A block is required to return the starting ActiveRecord scope.' unless block_given?
56
+
57
+ @config = {}
58
+ @config[:starting_scope] = block
59
+
60
+ params = params.deep_symbolize_keys
61
+
62
+ force_regex = params[:force_regex]
63
+
64
+ if params[:draw]
65
+ @config[:draw] = params[:draw].to_s.to_i
66
+ @config[:start] = params[:start].to_s.to_i
67
+ @config[:length] = params[:length].to_s.to_i
68
+ @config[:locate_id] = params[:locate_id].to_s.to_i
69
+
70
+
71
+ tmp = params[:search]
72
+ if tmp && !tmp[:value].blank?
73
+ if tmp[:regex].to_bool || force_regex
74
+ @config[:search] =
75
+ if tmp[:value].is_a?(::Regexp)
76
+ tmp[:value]
77
+ else
78
+ begin
79
+ Regexp.new(tmp[:value].to_s, Regexp::IGNORECASE)
80
+ rescue RegexpError
81
+ tmp[:value].to_s
82
+ end
83
+ end
84
+ elsif tmp
85
+ @config[:search] = tmp[:value].to_s
86
+ end
87
+ else
88
+ @config[:search] = nil
89
+ end
90
+
91
+ tmp = params[:columns]
92
+ @config[:columns] = [ ]
93
+ if tmp
94
+ tmp = tmp.each_with_index.to_a.map{|(a,b)| [b.to_s,a]}.to_h.deep_symbolize_keys if tmp.is_a?(::Array)
95
+ tmp.each do |id, col|
96
+ col[:id] = id.to_s.to_i
97
+ col[:name] = col[:data] if col[:name].blank?
98
+ col[:searchable] = col[:searchable].to_bool
99
+ col[:orderable] = col[:orderable].to_bool
100
+
101
+ if col[:search] && !col[:search][:value].blank?
102
+ if col[:search][:regex].to_bool || force_regex
103
+ col[:search] =
104
+ if col[:search][:value].is_a?(::Regexp)
105
+ col[:search][:value]
106
+ else
107
+ begin
108
+ Regexp.new(col[:search][:value].to_s, Regexp::IGNORECASE)
109
+ rescue RegexpError
110
+ col[:search][:value].to_s
111
+ end
112
+ end
113
+ else
114
+ col[:search] = col[:search][:value].to_s
115
+ end
116
+ else
117
+ col[:search] = nil
118
+ end
119
+
120
+ @config[:columns] << col
121
+ end
122
+ end
123
+ @config[:columns].freeze
124
+
125
+ tmp = params[:order]
126
+ @config[:order] = { }
127
+ if tmp
128
+ tmp = tmp.each_with_index.to_a.map{|(a,b)| [b.to_s,a]}.to_h.deep_symbolize_keys if tmp.is_a?(::Array)
129
+ tmp.each do |_, order|
130
+ col_id = order[:column].to_i
131
+ col = columns.find{|c| c[:id] == col_id}
132
+ if col
133
+ @config[:order][col[:name]] = ((order[:dir] || 'asc').downcase).to_sym
134
+ end
135
+ end
136
+ end
137
+ @config[:order].freeze
138
+ else
139
+ @config[:draw] = :not_provided
140
+ end
141
+
142
+ end
143
+
144
+ ##
145
+ # Where the data tables parameters provided?
146
+ def provided?
147
+ draw != :not_provided
148
+ end
149
+
150
+ ##
151
+ # Refreshes the data and returns the request instance.
152
+ def refresh!
153
+ records true
154
+ self
155
+ end
156
+
157
+ ##
158
+ # If #locate_id is non-zero, this is the record number for the specified ID using our filtering parameters.
159
+ #
160
+ # This will be an absolute zero-based record number for the ID. It can be used to figure out the page that the
161
+ # record would appear on.
162
+ def record_location(refresh = false)
163
+ @config[:record_location] = nil if refresh
164
+ @config[:record_location] ||= find_record
165
+ end
166
+
167
+ ##
168
+ # Gets the records returned by this request.
169
+ def records(refresh = false)
170
+ @config[:records] = nil if refresh
171
+ @config[:records] ||= load_records
172
+ end
173
+
174
+ ##
175
+ # Gets the total number of records before filtering.
176
+ def records_total
177
+ records
178
+ @config[:records_total]
179
+ end
180
+
181
+ ##
182
+ # Gets the total number of records after filtering.
183
+ def records_filtered
184
+ records
185
+ @config[:records_filtered]
186
+ end
187
+
188
+ ##
189
+ # The error message, if any?
190
+ def error
191
+ records
192
+ @config[:error]
193
+ end
194
+
195
+ ##
196
+ # Is there an error to display?
197
+ def error?
198
+ !error.blank?
199
+ end
200
+
201
+ private
202
+
203
+ ##
204
+ # Find the record represented by #locate_id.
205
+ def find_record(relation = nil)
206
+ return -1 if locate_id == 0
207
+
208
+ dataset = load_records(relation, false)
209
+ return -1 if dataset.blank?
210
+
211
+ return -1 unless dataset.first.respond_to?(:id)
212
+
213
+ dataset.index{|item| item.id == locate_id} || -1
214
+ end
215
+
216
+ ##
217
+ # Applies the request against an ActiveRecord::Relation object.
218
+ #
219
+ # Returns the results of executing the necessary queries and filters as an array of models.
220
+ def load_records(relation = nil, paging = true)
221
+ begin
222
+ # reset values.
223
+ # @config[:records] is set to the return of this method, we we won't change that here.
224
+ @config[:records_total] = 0
225
+ @config[:records_filtered] = 0
226
+ @config[:error] = nil
227
+
228
+ Incline::Log::debug "Loading records for data tables request #{draw}."
229
+
230
+ # Get the default starting scope if necessary.
231
+ relation ||= @config[:starting_scope].call
232
+
233
+ # store the unfiltered count.
234
+ @config[:records_total] = relation.count
235
+
236
+ # If any of these is true, then filtering must be done locally in our code.
237
+ filter_local = (
238
+ # main search is a regex.
239
+ search.is_a?(::Regexp) ||
240
+ # one or more column searches is a regex.
241
+ columns.select{|c| c[:search].is_a?(::Regexp)}.any? ||
242
+ # one or more searchable columns is not in the database model.
243
+ columns.reject {|c| !c[:searchable] || relation.model.column_names.include?(c[:name].to_s)}.any?
244
+ )
245
+
246
+ Incline::Log::debug "Filtering will be done #{filter_local ? 'application' : 'database'}-side."
247
+
248
+ unless filter_local
249
+ ### Database Side Individual Filtering (AND) ###
250
+ columns.reject{|c| c[:search].blank? || c[:name].blank?}.each do |col|
251
+ relation = relation.where("(UPPER(\"#{col[:name]}\") LIKE ?)", "%#{col[:search].upcase}%")
252
+ end
253
+
254
+ ### Database Side Multiple Filtering (OR) ###
255
+ unless search.blank?
256
+ srch = "%#{search.upcase}%"
257
+ cols = columns.select{|c| c[:searchable]}.map{|c| c[:name].to_s }.reject{|c| c.blank?}
258
+ if cols.any?
259
+ relation = relation.where(
260
+ cols.map{|c| "(UPPER(\"#{c}\") LIKE ?)"}.join(' OR '),
261
+ *(cols.map{ srch })
262
+ )
263
+ end
264
+ end
265
+ end
266
+
267
+ ### Database Side Ordering ###
268
+ if ordering.blank?
269
+ relation = relation.order(id: :asc)
270
+ else
271
+ relation = relation.order(ordering)
272
+ end
273
+
274
+ # Now we have two paths, if we are filtering locally, we need to return everything up to this point and
275
+ # perform our filters before limiting the results.
276
+ # If we filtered at the database, then we can limit the results there as well.
277
+ if filter_local
278
+ # execute the query
279
+ relation = relation.to_a
280
+
281
+ ### Local Individual Filtering (AND) ###
282
+ columns.reject{|c| c[:search].blank? || c[:name].blank?}.each do |col|
283
+ name = col[:name].to_s
284
+ srch = col[:search]
285
+ relation =
286
+ if srch.is_a?(::Regexp)
287
+ relation.select { |item| item.respond_to?(name) && item.send(name) =~ srch }
288
+ else
289
+ relation.select { |item| item.respond_to?(name) && item.send(name).to_s.include?(srch) }
290
+ end
291
+ end
292
+
293
+ ### Local Multiple Filtering ###
294
+ unless search.blank?
295
+ cols = columns.select{|c| c[:searchable]}.map{|c| c[:name].to_s }.reject{|c| c.blank?}
296
+ relation =
297
+ if search.is_a?(::Regexp)
298
+ relation.select{|item| cols.find{|col| item.respond_to?(col) && item.send(col) =~ search} }
299
+ else
300
+ relation.select{|item| cols.find{|col| item.respond_to?(col) && item.send(col).to_s.include?(search) }}
301
+ end
302
+ end
303
+
304
+ # store the filtered count.
305
+ @config[:records_filtered] = relation.count
306
+
307
+ if paging
308
+ # apply limits and return.
309
+ relation = relation[start..-1]
310
+ if length > 0
311
+ relation = relation[0...length]
312
+ end
313
+ end
314
+ relation
315
+ else
316
+ # store the filtered count.
317
+ @config[:records_filtered] = relation.count
318
+
319
+ if paging
320
+ # apply limits and return.
321
+ relation = relation.offset(start)
322
+ if length > 0
323
+ relation = relation.limit(length)
324
+ end
325
+ end
326
+ relation.to_a
327
+ end
328
+ rescue =>err
329
+ @config[:error] = err.message
330
+ Incline::Log::error err
331
+ [ ]
332
+ end
333
+ end
334
+
335
+ end
336
+ end
@@ -0,0 +1,6 @@
1
+ module Incline
2
+ module DateTimeFormats
3
+ US_DATE_FORMAT = /\A(?<MONTH>\d{1,2})\/(?<DAY>\d{1,2})\/(?<YEAR>(?:\d{2}|\d{4}))(?:\s+(?<HOUR>\d{1,2}):(?<MINUTE>\d{1,2})(?::(?<SECOND>\d{1,2})(?:\.(?<FRACTION>\d+))?)?(?:\s*(?<AMPM>[AP])M?)?)?\z/i
4
+ ALMOST_ISO_DATE_FORMAT = /\A(?<YEAR>\d{2,4})-(?<MONTH>\d{1,2})-(?<DAY>\d{1,2})(?:(T|\s+)(?<HOUR>\d{1,2}):(?<MINUTE>\d{1,2})(?::(?<SECOND>\d{1,2})(?:\.(?<FRACTION>\d+))?)?(?:\s*(?<AMPM>[AP])M?)?(?:\s*(?<TZ>(?:Z|[+-]\d{2}:?\d{2})))?)?\z/
5
+ end
6
+ end