barkest_core 1.5.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/Gemfile +22 -0
- data/Gemfile.lock +254 -0
- data/MIT-LICENSE +20 -0
- data/README.md +364 -0
- data/Rakefile +37 -0
- data/app/assets/fonts/barkest_core/ArchivoNarrow-Bold.ttf +0 -0
- data/app/assets/fonts/barkest_core/ArchivoNarrow-BoldItalic.ttf +0 -0
- data/app/assets/fonts/barkest_core/ArchivoNarrow-Italic.ttf +0 -0
- data/app/assets/fonts/barkest_core/ArchivoNarrow-Regular.ttf +0 -0
- data/app/assets/images/barkest_core/.keep +0 -0
- data/app/assets/images/barkest_core/barcode-B.svg +181 -0
- data/app/assets/javascripts/barkest_core/.keep +0 -0
- data/app/assets/javascripts/barkest_core/application.js +22 -0
- data/app/assets/javascripts/barkest_core/bootstrap-datepicker.js +1800 -0
- data/app/assets/javascripts/barkest_core/field_init.js +7 -0
- data/app/assets/javascripts/barkest_core/jquery.doubleScroll.js +112 -0
- data/app/assets/javascripts/barkest_core/masked_edit.js +25 -0
- data/app/assets/javascripts/barkest_core/system_status.js.erb +201 -0
- data/app/assets/stylesheets/barkest_core/.keep +0 -0
- data/app/assets/stylesheets/barkest_core/application.css +17 -0
- data/app/assets/stylesheets/barkest_core/custom.css.scss +264 -0
- data/app/assets/stylesheets/barkest_core/datepicker3.css +790 -0
- data/app/controllers/.keep +0 -0
- data/app/controllers/access_groups_controller.rb +74 -0
- data/app/controllers/account_activations_controller.rb +29 -0
- data/app/controllers/application_controller.rb +5 -0
- data/app/controllers/barkest_core/application_controller_base.rb +113 -0
- data/app/controllers/barkest_core/engine_controller_base.rb +15 -0
- data/app/controllers/barkest_core/testsub_controller.rb +21 -0
- data/app/controllers/contact_controller.rb +32 -0
- data/app/controllers/log_view_controller.rb +31 -0
- data/app/controllers/password_resets_controller.rb +126 -0
- data/app/controllers/sessions_controller.rb +64 -0
- data/app/controllers/status_controller.rb +150 -0
- data/app/controllers/system_config_controller.rb +238 -0
- data/app/controllers/system_update_controller.rb +164 -0
- data/app/controllers/test_access_controller.rb +44 -0
- data/app/controllers/test_report_controller.rb +75 -0
- data/app/controllers/users_controller.rb +218 -0
- data/app/helpers/.keep +0 -0
- data/app/helpers/barkest_core/application_helper.rb +134 -0
- data/app/helpers/barkest_core/form_helper.rb +469 -0
- data/app/helpers/barkest_core/html_helper.rb +70 -0
- data/app/helpers/barkest_core/misc_helper.rb +68 -0
- data/app/helpers/barkest_core/pdf_helper.rb +180 -0
- data/app/helpers/barkest_core/recaptcha_helper.rb +115 -0
- data/app/helpers/barkest_core/sessions_helper.rb +94 -0
- data/app/helpers/barkest_core/status_helper.rb +118 -0
- data/app/helpers/barkest_core/users_helper.rb +32 -0
- data/app/mailers/.keep +0 -0
- data/app/mailers/application_mailer.rb +5 -0
- data/app/mailers/barkest_core/application_mailer_base.rb +30 -0
- data/app/mailers/barkest_core/contact_form.rb +20 -0
- data/app/mailers/barkest_core/user_mailer.rb +44 -0
- data/app/models/.keep +0 -0
- data/app/models/access_group.rb +121 -0
- data/app/models/access_group_group_member.rb +13 -0
- data/app/models/access_group_user_member.rb +11 -0
- data/app/models/barkest_core/auth_config.rb +95 -0
- data/app/models/barkest_core/authorize_failure.rb +7 -0
- data/app/models/barkest_core/contact_message.rb +37 -0
- data/app/models/barkest_core/database_config.rb +223 -0
- data/app/models/barkest_core/db_table.rb +21 -0
- data/app/models/barkest_core/email_config.rb +132 -0
- data/app/models/barkest_core/global_status.rb +267 -0
- data/app/models/barkest_core/log_entry.rb +101 -0
- data/app/models/barkest_core/log_view_options.rb +51 -0
- data/app/models/barkest_core/ms_sql_db_definition.rb +441 -0
- data/app/models/barkest_core/ms_sql_definition.rb +221 -0
- data/app/models/barkest_core/ms_sql_function.rb +423 -0
- data/app/models/barkest_core/not_logged_in.rb +7 -0
- data/app/models/barkest_core/pdf_table_builder.rb +407 -0
- data/app/models/barkest_core/self_update_config.rb +37 -0
- data/app/models/barkest_core/user_alert.rb +29 -0
- data/app/models/barkest_core/user_alert_generators.rb +58 -0
- data/app/models/barkest_core/user_manager.rb +404 -0
- data/app/models/barkest_core/work_path.rb +74 -0
- data/app/models/disable_user.rb +18 -0
- data/app/models/ldap_access_group.rb +15 -0
- data/app/models/system_config.rb +99 -0
- data/app/models/user.rb +405 -0
- data/app/models/user_login_history.rb +11 -0
- data/app/views/.keep +0 -0
- data/app/views/access_groups/_form.html.erb +19 -0
- data/app/views/access_groups/edit.html.erb +2 -0
- data/app/views/access_groups/index.html.erb +32 -0
- data/app/views/access_groups/new.html.erb +2 -0
- data/app/views/access_groups/show.html.erb +4 -0
- data/app/views/barkest_core/contact_form/contact.html.erb +16 -0
- data/app/views/barkest_core/contact_form/contact.text.erb +13 -0
- data/app/views/barkest_core/testsub/_links.html.erb +5 -0
- data/app/views/barkest_core/testsub/page1.html.erb +3 -0
- data/app/views/barkest_core/testsub/page2.html.erb +2 -0
- data/app/views/barkest_core/testsub/page3.html.erb +2 -0
- data/app/views/barkest_core/user_mailer/account_activation.html.erb +7 -0
- data/app/views/barkest_core/user_mailer/account_activation.text.erb +6 -0
- data/app/views/barkest_core/user_mailer/invalid_password_reset.html.erb +3 -0
- data/app/views/barkest_core/user_mailer/invalid_password_reset.text.erb +5 -0
- data/app/views/barkest_core/user_mailer/password_reset.html.erb +8 -0
- data/app/views/barkest_core/user_mailer/password_reset.text.erb +7 -0
- data/app/views/contact/index.html.erb +24 -0
- data/app/views/layouts/_footer_copyright.html.erb +1 -0
- data/app/views/layouts/_menu_admin.html.erb +5 -0
- data/app/views/layouts/_menu_anon.html.erb +0 -0
- data/app/views/layouts/_menu_auth.html.erb +3 -0
- data/app/views/layouts/_menu_footer.html.erb +1 -0
- data/app/views/layouts/_nav_logo.html.erb +1 -0
- data/app/views/layouts/application.html.erb +2 -0
- data/app/views/layouts/barkest_core/_application.html.erb +24 -0
- data/app/views/layouts/barkest_core/_footer.html.erb +18 -0
- data/app/views/layouts/barkest_core/_header.html.erb +38 -0
- data/app/views/layouts/barkest_core/_html_mailer.html.erb +11 -0
- data/app/views/layouts/barkest_core/_menu_account.html.erb +14 -0
- data/app/views/layouts/barkest_core/_menu_sample.html.erb +1 -0
- data/app/views/layouts/barkest_core/_messages.html.erb +4 -0
- data/app/views/layouts/barkest_core/_shim.html.erb +4 -0
- data/app/views/layouts/barkest_core/_subheader.html.erb +1 -0
- data/app/views/layouts/barkest_core/_text_mailer.text.erb +4 -0
- data/app/views/layouts/mailer.html.erb +1 -0
- data/app/views/layouts/mailer.text.erb +1 -0
- data/app/views/log_view/index.html.erb +100 -0
- data/app/views/password_resets/edit.html.erb +20 -0
- data/app/views/password_resets/new.html.erb +14 -0
- data/app/views/sessions/new.html.erb +27 -0
- data/app/views/shared/_error_messages.html.erb +29 -0
- data/app/views/shared/_generic_user_alert.html.erb +4 -0
- data/app/views/status/current.html.erb +34 -0
- data/app/views/status/test.html.erb +50 -0
- data/app/views/system_config/index.html.erb +25 -0
- data/app/views/system_config/show_auth.html.erb +28 -0
- data/app/views/system_config/show_database.html.erb +36 -0
- data/app/views/system_config/show_email.html.erb +21 -0
- data/app/views/system_config/show_self_update.html.erb +13 -0
- data/app/views/system_update/index.html.erb +31 -0
- data/app/views/system_update/new.html.erb +2 -0
- data/app/views/test_access/allow_anon.html.erb +2 -0
- data/app/views/test_access/require_admin.html.erb +2 -0
- data/app/views/test_access/require_group_x.html.erb +2 -0
- data/app/views/test_access/require_user.html.erb +2 -0
- data/app/views/test_report/index.csv.csvrb +23 -0
- data/app/views/test_report/index.html.erb +6 -0
- data/app/views/test_report/index.pdf.prawn +50 -0
- data/app/views/test_report/index.xlsx.axlsx +28 -0
- data/app/views/users/_user.html.erb +57 -0
- data/app/views/users/_user_details.html.erb +15 -0
- data/app/views/users/_user_details_for_list.html.erb +1 -0
- data/app/views/users/_user_form.html.erb +13 -0
- data/app/views/users/disable_confirm.html.erb +19 -0
- data/app/views/users/edit.html.erb +15 -0
- data/app/views/users/index.html.erb +9 -0
- data/app/views/users/new.html.erb +10 -0
- data/app/views/users/show.html.erb +46 -0
- data/bin/rails +12 -0
- data/config/routes.rb +3 -0
- data/db/migrate/20160617172539_create_access_groups.rb +10 -0
- data/db/migrate/20160617172725_create_users.rb +26 -0
- data/db/migrate/20160617172833_create_user_login_histories.rb +12 -0
- data/db/migrate/20160622151720_create_access_group_user_members.rb +9 -0
- data/db/migrate/20160622151925_create_access_group_group_members.rb +9 -0
- data/db/migrate/20160701005706_create_ldap_access_groups.rb +11 -0
- data/db/migrate/20161108155029_create_system_configs.rb +11 -0
- data/db/seeds/barkest_core_01_create_users.rb +42 -0
- data/db/seeds.rb +53 -0
- data/lib/barkest_core/concerns/association_with_defaults.rb +55 -0
- data/lib/barkest_core/concerns/boolean_parser.rb +88 -0
- data/lib/barkest_core/concerns/date_parser.rb +181 -0
- data/lib/barkest_core/concerns/email_tester.rb +55 -0
- data/lib/barkest_core/concerns/encrypted_fields.rb +156 -0
- data/lib/barkest_core/concerns/named_model.rb +73 -0
- data/lib/barkest_core/concerns/number_parser.rb +145 -0
- data/lib/barkest_core/concerns/utc_conversion.rb +60 -0
- data/lib/barkest_core/engine.rb +105 -0
- data/lib/barkest_core/extensions/active_record_extensions.rb +120 -0
- data/lib/barkest_core/extensions/application_configuration_extensions.rb +38 -0
- data/lib/barkest_core/extensions/application_extensions.rb +50 -0
- data/lib/barkest_core/extensions/axlsx_extenstions.rb +157 -0
- data/lib/barkest_core/extensions/fixture_set_extensions.rb +107 -0
- data/lib/barkest_core/extensions/generator_extensions.rb +271 -0
- data/lib/barkest_core/extensions/main_app_extensions.rb +35 -0
- data/lib/barkest_core/extensions/prawn_document_extensions.rb +367 -0
- data/lib/barkest_core/extensions/prawn_table_extensions.rb +131 -0
- data/lib/barkest_core/extensions/router_extensions.rb +106 -0
- data/lib/barkest_core/extensions/simple_formatter_extensions.rb +66 -0
- data/lib/barkest_core/extensions/test_case_extensions.rb +348 -0
- data/lib/barkest_core/extensions/time_extensions.rb +164 -0
- data/lib/barkest_core/handlers/csv_handler.rb +30 -0
- data/lib/barkest_core/version.rb +3 -0
- data/lib/barkest_core.rb +324 -0
- data/lib/generators/barkest/install_generator.rb +102 -0
- data/lib/generators/barkest_core/actions/01_patch_application_controller.rb +55 -0
- data/lib/generators/barkest_core/actions/02_patch_application_mailer.rb +56 -0
- data/lib/generators/barkest_core/actions/03_patch_assets.rb +62 -0
- data/lib/generators/barkest_core/actions/04_patch_layouts.rb +36 -0
- data/lib/generators/barkest_core/actions/05_patch_routes.rb +93 -0
- data/lib/generators/barkest_core/actions/06_patch_seeds.rb +60 -0
- data/lib/generators/barkest_core/actions/07_copy_migrations.rb +51 -0
- data/lib/generators/barkest_core/actions/08_configure_database.rb +52 -0
- data/lib/generators/barkest_core/actions/09_configure_secrets.rb +29 -0
- data/lib/generators/barkest_core/actions/99_patch_gitignore.rb +57 -0
- data/lib/generators/barkest_core/install_generator.rb +17 -0
- data/test/barkest_core_test.rb +83 -0
- data/test/controllers/access_groups_controller_test.rb +53 -0
- data/test/controllers/contact_controller_test.rb +10 -0
- data/test/controllers/sessions_controller_test.rb +10 -0
- data/test/controllers/users_controller_test.rb +10 -0
- data/test/dummy/.gitignore +10 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/images/.keep +0 -0
- data/test/dummy/app/assets/javascripts/application.js +14 -0
- data/test/dummy/app/assets/stylesheets/application.css +16 -0
- data/test/dummy/app/controllers/application_controller.rb +5 -0
- data/test/dummy/app/controllers/concerns/.keep +0 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/mailers/.keep +0 -0
- data/test/dummy/app/mailers/application_mailer.rb +3 -0
- data/test/dummy/app/models/.keep +0 -0
- data/test/dummy/app/models/concerns/.keep +0 -0
- data/test/dummy/app/views/layouts/application.html.erb +1 -0
- data/test/dummy/app/views/layouts/mailer.html.erb +1 -0
- data/test/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/test/dummy/app/views/system_config/show_fake.html.erb +3 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/bin/setup +29 -0
- data/test/dummy/config/application.rb +27 -0
- data/test/dummy/config/boot.rb +5 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +47 -0
- data/test/dummy/config/environments/production.rb +79 -0
- data/test/dummy/config/environments/test.rb +44 -0
- data/test/dummy/config/initializers/assets.rb +11 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/test/dummy/config/initializers/db_updater_ext.rb +33 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +4 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/sys_config_ext.rb +12 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +23 -0
- data/test/dummy/config/routes.rb +60 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/db/schema.rb +95 -0
- data/test/dummy/db/seeds/barkest_core_01_create_users.rb +42 -0
- data/test/dummy/db/seeds.rb +51 -0
- data/test/dummy/lib/assets/.keep +0 -0
- data/test/dummy/log/.keep +0 -0
- data/test/dummy/public/404.html +67 -0
- data/test/dummy/public/422.html +67 -0
- data/test/dummy/public/500.html +66 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/sql/my_test_view.sql +3 -0
- data/test/fixtures/access_groups.yml +21 -0
- data/test/fixtures/users.yml +71 -0
- data/test/helpers/barkest_core/sessions_helper_test.rb +22 -0
- data/test/integration/access_group_mgmt_test.rb +33 -0
- data/test/integration/access_test.rb +24 -0
- data/test/integration/account_activations_access_test.rb +12 -0
- data/test/integration/contact_test.rb +98 -0
- data/test/integration/extra_partial_test.rb +41 -0
- data/test/integration/log_view_access_test.rb +12 -0
- data/test/integration/password_resets_test.rb +101 -0
- data/test/integration/reports_test.rb +53 -0
- data/test/integration/status_access_test.rb +27 -0
- data/test/integration/system_config_access_test.rb +24 -0
- data/test/integration/system_update_access_test.rb +19 -0
- data/test/integration/users_access_test.rb +34 -0
- data/test/integration/users_edit_test.rb +178 -0
- data/test/integration/users_index_test.rb +62 -0
- data/test/integration/users_login_test.rb +67 -0
- data/test/integration/users_signup_test.rb +54 -0
- data/test/mailers/.keep +0 -0
- data/test/mailers/barkest_core/contact_form_test.rb +28 -0
- data/test/mailers/barkest_core/user_mailer_test.rb +43 -0
- data/test/mailers/previews/barkest_core/contact_form_preview.rb +17 -0
- data/test/mailers/previews/barkest_core/user_mailer_preview.rb +26 -0
- data/test/models/access_group_group_member_test.rb +28 -0
- data/test/models/access_group_test.rb +114 -0
- data/test/models/access_group_user_member_test.rb +28 -0
- data/test/models/barkest_core/auth_config_test.rb +57 -0
- data/test/models/barkest_core/bool_parser_test.rb +28 -0
- data/test/models/barkest_core/contact_message_test.rb +61 -0
- data/test/models/barkest_core/database_config_test.rb +33 -0
- data/test/models/barkest_core/date_parser_test.rb +110 -0
- data/test/models/barkest_core/email_config_test.rb +57 -0
- data/test/models/barkest_core/global_status_test.rb +50 -0
- data/test/models/barkest_core/ms_sql_db_updater_test.rb +115 -0
- data/test/models/barkest_core/ms_sql_definition_test.rb +102 -0
- data/test/models/barkest_core/ms_sql_function_test.rb +131 -0
- data/test/models/barkest_core/number_parser_test.rb +29 -0
- data/test/models/barkest_core/self_update_config_test.rb +29 -0
- data/test/models/barkest_core/user_alert_test.rb +19 -0
- data/test/models/barkest_core/user_manager_test.rb +34 -0
- data/test/models/barkest_core/work_path_test.rb +26 -0
- data/test/models/disable_user_test.rb +27 -0
- data/test/models/generic_time_test.rb +66 -0
- data/test/models/ldap_access_group_test.rb +31 -0
- data/test/models/pdf_table_builder_test.rb +6 -0
- data/test/models/system_config_test.rb +78 -0
- data/test/models/user_login_history_test.rb +37 -0
- data/test/models/user_test.rb +130 -0
- data/test/test_helper.rb +63 -0
- metadata +798 -0
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
require 'tmpdir'
|
|
2
|
+
|
|
3
|
+
module BarkestCore
|
|
4
|
+
##
|
|
5
|
+
# This class simply locates a temporary working directory for the application.
|
|
6
|
+
#
|
|
7
|
+
# By default we shoot for shared memory such as /run/shm or /dev/shm. If those
|
|
8
|
+
# fail, we look to /tmp.
|
|
9
|
+
#
|
|
10
|
+
class WorkPath
|
|
11
|
+
|
|
12
|
+
##
|
|
13
|
+
# Gets the temporary working directory location for the application.
|
|
14
|
+
#
|
|
15
|
+
def self.location
|
|
16
|
+
@location ||=
|
|
17
|
+
begin
|
|
18
|
+
retval = nil
|
|
19
|
+
%w(/run/shm /var/run/shm /dev/shm /tmp).each do |root|
|
|
20
|
+
if Dir.exist?(root)
|
|
21
|
+
retval = try_path(root)
|
|
22
|
+
break if retval
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
retval || try_path(Dir.tmpdir)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
##
|
|
30
|
+
# Gets a path for a specific temporary file.
|
|
31
|
+
#
|
|
32
|
+
def self.path_for(filename)
|
|
33
|
+
raise StandardError.new('Cannot determine location.') unless location
|
|
34
|
+
location + '/' + filename
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
##
|
|
38
|
+
# Gets the path to the system status file.
|
|
39
|
+
#
|
|
40
|
+
# This file is used by long running processes to log their progress.
|
|
41
|
+
#
|
|
42
|
+
def self.system_status_file
|
|
43
|
+
@system_status_file ||= path_for('system_status')
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
|
|
48
|
+
def self.app_name
|
|
49
|
+
@app_name ||=
|
|
50
|
+
if Rails.application.respond_to?(:app_name)
|
|
51
|
+
Rails.application.app_name.underscore
|
|
52
|
+
else
|
|
53
|
+
Rails.application.class.name.underscore
|
|
54
|
+
end.gsub('/','-')
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def self.try_path(path)
|
|
58
|
+
return nil if path.blank?
|
|
59
|
+
path = path.gsub('\\', '/')
|
|
60
|
+
path = path[0...-1] if path[-1] == '/'
|
|
61
|
+
path += '/barkest_' + app_name
|
|
62
|
+
return nil unless (Dir.exist?(path) || Dir.mkdir(path))
|
|
63
|
+
begin
|
|
64
|
+
test_file = path + '/test.file'
|
|
65
|
+
File.write(test_file, app_name)
|
|
66
|
+
File.delete(test_file)
|
|
67
|
+
rescue
|
|
68
|
+
return nil
|
|
69
|
+
end
|
|
70
|
+
path
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
##
|
|
2
|
+
# This model is used to disable a user with a reason for the disabling.
|
|
3
|
+
class DisableUser
|
|
4
|
+
include ActiveModel::Model
|
|
5
|
+
include ActiveModel::Validations
|
|
6
|
+
|
|
7
|
+
attr_accessor :reason, :user
|
|
8
|
+
|
|
9
|
+
validates :reason, presence: true
|
|
10
|
+
validate do
|
|
11
|
+
if user && user.is_a?(User)
|
|
12
|
+
errors.add(:user, 'must be enabled') unless user.enabled?
|
|
13
|
+
else
|
|
14
|
+
errors.add(:user, 'must be provided')
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
##
|
|
2
|
+
# Defines an LDAP group that belongs to an Access Group.
|
|
3
|
+
class LdapAccessGroup < ::BarkestCore::DbTable
|
|
4
|
+
|
|
5
|
+
belongs_to :group, class_name: 'AccessGroup'
|
|
6
|
+
|
|
7
|
+
validates :group,
|
|
8
|
+
presence: true
|
|
9
|
+
|
|
10
|
+
validates :name,
|
|
11
|
+
presence: true,
|
|
12
|
+
length: { maximum: 200 },
|
|
13
|
+
uniqueness: { case_sensitive: false, scope: :group_id }
|
|
14
|
+
|
|
15
|
+
end
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
require 'encrypted_strings'
|
|
2
|
+
|
|
3
|
+
##
|
|
4
|
+
# Defines a mechanism to store and retrieve configurations using the core database.
|
|
5
|
+
#
|
|
6
|
+
# The +get+ and +set+ methods allow values to be stored in an encrypted fashion as well.
|
|
7
|
+
#
|
|
8
|
+
# The encryption will use the +encrypted_config_key+ value or the +secret_key_base+ value from
|
|
9
|
+
# +secrets.yml+. Ideally, use +encrypted_config_key+ to allow +secret_key_base+ to change if
|
|
10
|
+
# necessary.
|
|
11
|
+
class SystemConfig < ::BarkestCore::DbTable
|
|
12
|
+
|
|
13
|
+
validates :key,
|
|
14
|
+
presence: true,
|
|
15
|
+
length: { maximum: 128 },
|
|
16
|
+
uniqueness: { case_sensitive: false }
|
|
17
|
+
|
|
18
|
+
before_save :downcase_key
|
|
19
|
+
|
|
20
|
+
##
|
|
21
|
+
# Sets the value storing it as a YAML string.
|
|
22
|
+
def value=(new_value)
|
|
23
|
+
val = new_value.nil? ? nil : new_value.to_yaml
|
|
24
|
+
write_attribute :value, val
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
##
|
|
28
|
+
# Gets the value loading it from a YAML string.
|
|
29
|
+
def value
|
|
30
|
+
val = read_attribute(:value).to_s
|
|
31
|
+
return nil if val.empty?
|
|
32
|
+
YAML.load val
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
##
|
|
36
|
+
# Gets a value from the database.
|
|
37
|
+
#
|
|
38
|
+
# If the value was stored encrypted, it will be decrypted before being returned.
|
|
39
|
+
#
|
|
40
|
+
# As a feature during testing +config/key_name.yml+ will be used if it exists and the database
|
|
41
|
+
# value is missing.
|
|
42
|
+
#
|
|
43
|
+
def self.get(key_name)
|
|
44
|
+
begin
|
|
45
|
+
record = where(key: key_name.to_s.downcase).first
|
|
46
|
+
|
|
47
|
+
if record
|
|
48
|
+
value = record.value
|
|
49
|
+
if value.is_a?(Hash) && value.keys.include?(:encrypted_value)
|
|
50
|
+
value = value[:encrypted_value]
|
|
51
|
+
unless value.nil? || value == ''
|
|
52
|
+
value = YAML.load(crypto_cipher.decrypt(value)) rescue nil
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
elsif Rails.env.test?
|
|
56
|
+
yml_file = "#{BarkestCore.app_root}/config/#{key_name}.yml"
|
|
57
|
+
value = File.exist?(yml_file) ? YAML.load_file(yml_file) : nil
|
|
58
|
+
else
|
|
59
|
+
value = nil
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
value
|
|
63
|
+
rescue
|
|
64
|
+
nil # if 'system_configs' table has not been created, return nil.
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
##
|
|
69
|
+
# Stores a value to the database.
|
|
70
|
+
#
|
|
71
|
+
# All values are converted into YAML strings before storage.
|
|
72
|
+
#
|
|
73
|
+
# If +encrypt+ is set to true, then the value will be encrypted before being stored.
|
|
74
|
+
def self.set(key_name, value, encrypt = false)
|
|
75
|
+
key_name = key_name.to_s.downcase
|
|
76
|
+
if encrypt
|
|
77
|
+
value = crypto_cipher.encrypt(value.to_yaml) unless value.nil? || value == ''
|
|
78
|
+
value = { encrypted_value: value }
|
|
79
|
+
end
|
|
80
|
+
record = find_or_initialize_by(key: key_name)
|
|
81
|
+
record.value = value
|
|
82
|
+
record.save
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
private
|
|
86
|
+
|
|
87
|
+
def self.crypto_password
|
|
88
|
+
@crypto_password ||= Rails.application.secrets[:encrypted_config_key] || Rails.application.secrets[:secret_key_base]
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def self.crypto_cipher
|
|
92
|
+
@crypto_cipher ||= EncryptedStrings::SymmetricCipher.new(password: crypto_password)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def downcase_key
|
|
96
|
+
key.downcase!
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
end
|
data/app/models/user.rb
ADDED
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
##
|
|
2
|
+
# The user class defines the individual users in the application.
|
|
3
|
+
#
|
|
4
|
+
# Each user can login with their email address, if the domain portion of their
|
|
5
|
+
# email address happens to match an LdapSource, then that LdapSource will be
|
|
6
|
+
# used to authenticate them, otherwise the +password_digest+ stored in the
|
|
7
|
+
# database will be used to authenticate them.
|
|
8
|
+
class User < ::BarkestCore::DbTable
|
|
9
|
+
|
|
10
|
+
ANONYMOUS_EMAIL = 'anonymous@local.server'
|
|
11
|
+
|
|
12
|
+
UNIQUE_STRING_FIELD = :email
|
|
13
|
+
include BarkestCore::NamedModel
|
|
14
|
+
include BarkestCore::EmailTester
|
|
15
|
+
|
|
16
|
+
has_many :access_group_user_members, class_name: 'AccessGroupUserMember', foreign_key: 'member_id'
|
|
17
|
+
private :access_group_user_members, :access_group_user_members=
|
|
18
|
+
|
|
19
|
+
has_many :groups, class_name: 'AccessGroup', through: :access_group_user_members
|
|
20
|
+
|
|
21
|
+
has_many :login_histories, :class_name => 'UserLoginHistory'
|
|
22
|
+
|
|
23
|
+
belongs_to :disabled_by, class_name: 'User'
|
|
24
|
+
|
|
25
|
+
before_save :downcase_email
|
|
26
|
+
before_create :create_activation_digest
|
|
27
|
+
|
|
28
|
+
##
|
|
29
|
+
# Gets the temporary token used to remember this user.
|
|
30
|
+
attr_accessor :remember_token
|
|
31
|
+
|
|
32
|
+
##
|
|
33
|
+
# Gets the temporary token used to activate this user.
|
|
34
|
+
attr_accessor :activation_token
|
|
35
|
+
|
|
36
|
+
##
|
|
37
|
+
# Gets the temporary token used to reset this user's password.
|
|
38
|
+
attr_accessor :reset_token
|
|
39
|
+
|
|
40
|
+
has_secure_password
|
|
41
|
+
|
|
42
|
+
validates :name,
|
|
43
|
+
presence: true,
|
|
44
|
+
length: { maximum: 100 }
|
|
45
|
+
|
|
46
|
+
validates :email,
|
|
47
|
+
presence: true,
|
|
48
|
+
length: { maximum: 255 },
|
|
49
|
+
uniqueness: { case_sensitive: false },
|
|
50
|
+
format: { with: VALID_EMAIL_REGEX }
|
|
51
|
+
|
|
52
|
+
validates :disabled_reason,
|
|
53
|
+
length: { maximum: 200 }
|
|
54
|
+
|
|
55
|
+
validates :last_ip,
|
|
56
|
+
length: { maximum: 64 }
|
|
57
|
+
|
|
58
|
+
validates :password,
|
|
59
|
+
presence: true,
|
|
60
|
+
length: { minimum: 6 },
|
|
61
|
+
allow_nil: true
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
##
|
|
65
|
+
# Gets the email address in a partially obfuscated fashion.
|
|
66
|
+
def partial_email
|
|
67
|
+
uid,_,domain = email.partition('@')
|
|
68
|
+
if uid.length < 4
|
|
69
|
+
uid = '*' * uid.length
|
|
70
|
+
elsif uid.length < 8
|
|
71
|
+
uid = uid[0..2] + ('*' * (uid.length - 3))
|
|
72
|
+
else
|
|
73
|
+
uid = uid[0..2] + ('*' * (uid.length - 6)) + uid[-3..-1]
|
|
74
|
+
end
|
|
75
|
+
"#{uid}@#{domain}"
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
##
|
|
79
|
+
# Is the user a system administrator?
|
|
80
|
+
def system_admin?
|
|
81
|
+
enabled && system_admin
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
##
|
|
85
|
+
# Gets the effective group membership of this user.
|
|
86
|
+
def effective_groups(refresh = false)
|
|
87
|
+
@effective_groups = nil if refresh
|
|
88
|
+
@effective_groups ||= if system_admin?
|
|
89
|
+
AccessGroup.all.map{ |g| g.to_s.upcase }
|
|
90
|
+
else
|
|
91
|
+
groups
|
|
92
|
+
.collect{ |g| g.effective_groups }
|
|
93
|
+
.flatten
|
|
94
|
+
.inject([]){ |memo,item| memo << item unless memo.include?(item); memo }
|
|
95
|
+
end
|
|
96
|
+
.map{ |g| g.to_s.upcase }
|
|
97
|
+
.sort
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
##
|
|
101
|
+
# Does this user have the equivalent of one or more of these groups?
|
|
102
|
+
def has_any_group?(*group_list)
|
|
103
|
+
return true if system_admin?
|
|
104
|
+
|
|
105
|
+
group_list.each do |group|
|
|
106
|
+
group = group.to_s.upcase
|
|
107
|
+
return true if effective_groups.include?(group)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
false
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
##
|
|
114
|
+
# Generates a remember token and saves the digest to the user model.
|
|
115
|
+
def remember
|
|
116
|
+
self.remember_token = User.new_token
|
|
117
|
+
update_attribute(:remember_digest, User.digest(self.remember_token))
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
##
|
|
121
|
+
# Removes the remember digest from the user model.
|
|
122
|
+
def forget
|
|
123
|
+
update_attribute(:remember_digest, nil)
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
##
|
|
127
|
+
# Determines if the supplied token digests to the stored digest in the user model.
|
|
128
|
+
def authenticated?(attribute, token)
|
|
129
|
+
return false unless respond_to?("#{attribute}_digest")
|
|
130
|
+
digest = send("#{attribute}_digest")
|
|
131
|
+
return false if digest.blank?
|
|
132
|
+
BCrypt::Password.new(digest).is_password?(token)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
##
|
|
136
|
+
# Disables the user.
|
|
137
|
+
#
|
|
138
|
+
# The +other_user+ is required, cannot be the current user, and must be a system administrator.
|
|
139
|
+
# The +reason+ is technically optional, but should be provided.
|
|
140
|
+
def disable(other_user, reason)
|
|
141
|
+
return false unless other_user && other_user.system_admin?
|
|
142
|
+
return false if other_user == self
|
|
143
|
+
|
|
144
|
+
update_columns(
|
|
145
|
+
disabled_by_id: other_user.id,
|
|
146
|
+
disabled_at: Time.zone.now,
|
|
147
|
+
disabled_reason: reason,
|
|
148
|
+
enabled: false
|
|
149
|
+
)
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
##
|
|
153
|
+
# Enables the user and removes any previous disable information.
|
|
154
|
+
def enable
|
|
155
|
+
update_columns(
|
|
156
|
+
disabled_by_id: nil,
|
|
157
|
+
disabled_at: nil,
|
|
158
|
+
disabled_reason: nil,
|
|
159
|
+
enabled: true
|
|
160
|
+
)
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
##
|
|
165
|
+
# Marks the user as activated and removes the activation digest from the user model.
|
|
166
|
+
def activate
|
|
167
|
+
update_columns(
|
|
168
|
+
activated: true,
|
|
169
|
+
activated_at: Time.zone.now,
|
|
170
|
+
activation_digest: nil
|
|
171
|
+
)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
##
|
|
175
|
+
# Sends the activation email to the user.
|
|
176
|
+
def send_activation_email(client_ip = '0.0.0.0')
|
|
177
|
+
BarkestCore::UserMailer.account_activation(user: self, client_ip: client_ip).deliver_now
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
##
|
|
181
|
+
# Creates a reset token and stores the digest to the user model.
|
|
182
|
+
def create_reset_digest
|
|
183
|
+
self.reset_token = User.new_token
|
|
184
|
+
update_columns(
|
|
185
|
+
reset_digest: User.digest(reset_token),
|
|
186
|
+
reset_sent_at: Time.zone.now
|
|
187
|
+
)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
##
|
|
191
|
+
# Was the password reset requested more than 2 hours ago?
|
|
192
|
+
def password_reset_expired?
|
|
193
|
+
reset_sent_at.nil? || reset_sent_at < 2.hours.ago
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
##
|
|
197
|
+
# Is this the anonymous user?
|
|
198
|
+
def anonymous?
|
|
199
|
+
email == ANONYMOUS_EMAIL
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
##
|
|
203
|
+
# Gets the last successful login for this user.
|
|
204
|
+
def last_successful_login
|
|
205
|
+
@last_successful_login ||= login_histories.where(successful: true).order(created_at: :desc).first
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
##
|
|
209
|
+
# Gets the last failed login for this user.
|
|
210
|
+
def last_failed_login
|
|
211
|
+
@last_failed_login ||= login_histories.where.not(successful: true).order(created_at: :desc).first
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
##
|
|
215
|
+
# Gets the failed logins for a user since the last successful login.
|
|
216
|
+
def failed_login_streak
|
|
217
|
+
@failed_login_streak ||=
|
|
218
|
+
begin
|
|
219
|
+
results = login_histories.where.not(successful: true)
|
|
220
|
+
if last_successful_login
|
|
221
|
+
results = results.where('created_at > ?', last_successful_login.created_at)
|
|
222
|
+
end
|
|
223
|
+
results.order(created_at: :desc)
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def settings(reload = false)
|
|
228
|
+
@settings = nil if reload
|
|
229
|
+
@settings ||=
|
|
230
|
+
begin
|
|
231
|
+
h = SystemConfig.get("user_#{id}") || {}
|
|
232
|
+
h.instance_variable_set :@user_id, id
|
|
233
|
+
|
|
234
|
+
def h.save
|
|
235
|
+
SystemConfig.set "user_#{@user_id}", self
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def h.method_missing(m,*a,&b)
|
|
239
|
+
x = (/^([A-Z][A-Z0-9_]*)(=)?$/i).match(m.to_s)
|
|
240
|
+
if x
|
|
241
|
+
key = x[1].to_sym
|
|
242
|
+
if x[2] == '='
|
|
243
|
+
val = a ? a.first : nil
|
|
244
|
+
self[key] = val
|
|
245
|
+
return val
|
|
246
|
+
else
|
|
247
|
+
return self[key]
|
|
248
|
+
end
|
|
249
|
+
end
|
|
250
|
+
super m, *a, &b
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
def h.[](key)
|
|
254
|
+
super key.to_sym
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
def h.[]=(key, value)
|
|
258
|
+
super key.to_sym, value
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
h
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
##
|
|
266
|
+
# Sends the password reset email to the user.
|
|
267
|
+
def send_password_reset_email(client_ip = '0.0.0.0')
|
|
268
|
+
BarkestCore::UserMailer.password_reset(user: self, client_ip: client_ip).deliver_now
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
##
|
|
272
|
+
# Sends a missing account message when a user requests a password reset.
|
|
273
|
+
def self.send_missing_reset_email(email, client_ip = '0.0.0.0')
|
|
274
|
+
BarkestCore::UserMailer::invalid_password_reset(email: email, client_ip: client_ip).deliver_now
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
##
|
|
278
|
+
# Sends a disabled account message when a user requests a password reset.
|
|
279
|
+
def self.send_disabled_reset_email(email, client_ip = '0.0.0.0')
|
|
280
|
+
BarkestCore::UserMailer::invalid_password_reset(email: email, message: 'The account attached to this email address has been disabled.', client_ip: client_ip).deliver_now
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
##
|
|
284
|
+
# Sends a non-activated account message when a user requests a password reset.
|
|
285
|
+
def self.send_inactive_reset_email(email, client_ip = '0.0.0.0')
|
|
286
|
+
BarkestCore::UserMailer::invalid_password_reset(email: email, message: 'The account attached to this email has not yet been activated.', client_ip: client_ip).deliver_now
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
##
|
|
290
|
+
# Sends a message informing the user we cannot change LDAP passwords.
|
|
291
|
+
def self.send_ldap_reset_email(email, client_ip = '0.0.0.0')
|
|
292
|
+
BarkestCore::UserMailer::invalid_password_reset(email: email, message: 'The account attached to this email is an LDAP account. This application cannot change passwords on an LDAP account.', client_ip: client_ip).deliver_now
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
##
|
|
296
|
+
# Returns a hash digest of the given string.
|
|
297
|
+
def self.digest(string)
|
|
298
|
+
cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost
|
|
299
|
+
BCrypt::Password.create(string, cost: cost)
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
##
|
|
303
|
+
# Generates a new random token in (url safe) base64.
|
|
304
|
+
def self.new_token
|
|
305
|
+
SecureRandom.urlsafe_base64(32)
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
##
|
|
309
|
+
# Gets all known users.
|
|
310
|
+
def self.known
|
|
311
|
+
where.not(email: ANONYMOUS_EMAIL)
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
##
|
|
315
|
+
# Gets all of the currently enabled users.
|
|
316
|
+
def self.enabled
|
|
317
|
+
where(enabled: true, activated: true)
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
##
|
|
321
|
+
# Sorts the users by name.
|
|
322
|
+
def self.sorted
|
|
323
|
+
order(name: :asc)
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
##
|
|
327
|
+
# Generates the necessary system administrator account.
|
|
328
|
+
#
|
|
329
|
+
# When the database is initially seeded, the only user is the system administrator.
|
|
330
|
+
# The system administrator is **admin@barkerest.com** and the password is initially **Password1**.
|
|
331
|
+
# You should change this immediately once the app is running. You will most likely want to create
|
|
332
|
+
# a completely new admin account and disable the **admin@barkerest.com** account.
|
|
333
|
+
def self.ensure_admin_exists!
|
|
334
|
+
unless where(system_admin: true, enabled: true).count > 0
|
|
335
|
+
|
|
336
|
+
msg = "Creating/reactivating default administrator...\n"
|
|
337
|
+
if Rails.application.running?
|
|
338
|
+
Rails.logger.info msg
|
|
339
|
+
else
|
|
340
|
+
print msg
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
def_adm_email = 'admin@barkerest.com'
|
|
344
|
+
def_adm_pass = 'Password1'
|
|
345
|
+
|
|
346
|
+
user = User
|
|
347
|
+
.where(
|
|
348
|
+
email: def_adm_email
|
|
349
|
+
)
|
|
350
|
+
.first_or_create!(
|
|
351
|
+
name: 'Default Administrator',
|
|
352
|
+
email: def_adm_email,
|
|
353
|
+
password: def_adm_pass,
|
|
354
|
+
password_confirmation: def_adm_pass,
|
|
355
|
+
enabled: true,
|
|
356
|
+
system_admin: true,
|
|
357
|
+
activated: true,
|
|
358
|
+
activated_at: Time.zone.now
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
unless user.enabled? && user.system_admin?
|
|
362
|
+
user.password = def_adm_pass
|
|
363
|
+
user.password_confirmation = def_adm_pass
|
|
364
|
+
user.enabled = true
|
|
365
|
+
user.system_admin = true
|
|
366
|
+
user.activated = true
|
|
367
|
+
user.activated_at = Time.zone.now
|
|
368
|
+
user.save!
|
|
369
|
+
end
|
|
370
|
+
end
|
|
371
|
+
end
|
|
372
|
+
|
|
373
|
+
##
|
|
374
|
+
# Gets a generic anonymous user.
|
|
375
|
+
def self.anonymous
|
|
376
|
+
@anonymous = nil if Rails.env.test?
|
|
377
|
+
@anonymous ||=
|
|
378
|
+
begin
|
|
379
|
+
pwd = new_token
|
|
380
|
+
where(email: ANONYMOUS_EMAIL)
|
|
381
|
+
.first_or_create(
|
|
382
|
+
email: ANONYMOUS_EMAIL,
|
|
383
|
+
name: 'Anonymous',
|
|
384
|
+
enabled: false,
|
|
385
|
+
activated: true,
|
|
386
|
+
activated_at: Time.zone.now,
|
|
387
|
+
password: pwd,
|
|
388
|
+
password_confirmation: pwd
|
|
389
|
+
)
|
|
390
|
+
end
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
private
|
|
395
|
+
|
|
396
|
+
def downcase_email
|
|
397
|
+
email.downcase!
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
def create_activation_digest
|
|
401
|
+
self.activation_token = User.new_token
|
|
402
|
+
self.activation_digest = User.digest(activation_token)
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
end
|