incline 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
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