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,29 @@
|
|
|
1
|
+
module BarkestCore
|
|
2
|
+
##
|
|
3
|
+
# This model provides informational alerts to the user.
|
|
4
|
+
class UserAlert
|
|
5
|
+
include ActiveModel::Model
|
|
6
|
+
include ActiveModel::Validations
|
|
7
|
+
|
|
8
|
+
attr_accessor :message, :model
|
|
9
|
+
|
|
10
|
+
validates :message, presence: true
|
|
11
|
+
|
|
12
|
+
def type
|
|
13
|
+
@type || :info
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def type=(value)
|
|
17
|
+
@type = value ? value.to_s.to_sym : nil
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def view
|
|
21
|
+
@view || 'generic_user_alert'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def view=(value)
|
|
25
|
+
@view = value.blank? ? nil : value.to_s
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
module BarkestCore
|
|
2
|
+
##
|
|
3
|
+
# A repository for user alert generators.
|
|
4
|
+
#
|
|
5
|
+
# Register any alert generators that you want to give the user automatically at login.
|
|
6
|
+
#
|
|
7
|
+
class UserAlertGenerators
|
|
8
|
+
|
|
9
|
+
##
|
|
10
|
+
# Enumerates all of the generators that have been registered.
|
|
11
|
+
#
|
|
12
|
+
# Yields the +type+ and +generator+.
|
|
13
|
+
def self.each(&block)
|
|
14
|
+
return unless block_given?
|
|
15
|
+
list.each do |type,generators|
|
|
16
|
+
generators.each do |generator|
|
|
17
|
+
yield type, generator
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
##
|
|
23
|
+
# Gets all of the generators that have been registered.
|
|
24
|
+
#
|
|
25
|
+
# This list does not include the type.
|
|
26
|
+
def self.all
|
|
27
|
+
list.values.flatten.freeze
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
##
|
|
31
|
+
# Gets a subset of the generators that have been registered.
|
|
32
|
+
#
|
|
33
|
+
# Provide the type of generators you would like to return.
|
|
34
|
+
def self.[](type)
|
|
35
|
+
type ||= :info
|
|
36
|
+
type = type.to_sym
|
|
37
|
+
(list[type] || []).freeze
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
##
|
|
41
|
+
# Registers an alert generator.
|
|
42
|
+
#
|
|
43
|
+
# The generator shold be designed to take a User model as an argument.
|
|
44
|
+
def self.register(type = nil, &block)
|
|
45
|
+
type ||= :info
|
|
46
|
+
type = type.to_sym
|
|
47
|
+
list[type] ||= []
|
|
48
|
+
list[type] << block
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def self.list
|
|
54
|
+
@list ||= {}
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
require 'net-ldap'
|
|
2
|
+
|
|
3
|
+
module BarkestCore
|
|
4
|
+
##
|
|
5
|
+
# Handles login requests, group mapping, and password changing for both the DB and LDAP sources.
|
|
6
|
+
#
|
|
7
|
+
class UserManager
|
|
8
|
+
|
|
9
|
+
##
|
|
10
|
+
# Creates a new user manager.
|
|
11
|
+
def initialize(options = {})
|
|
12
|
+
@options = (options || {}).symbolize_keys
|
|
13
|
+
if @options[:enable_ldap_auth]
|
|
14
|
+
@ldap = get_ldap_connection
|
|
15
|
+
raise ArgumentError.new('Failed to connect to LDAP host using supplied arguments.') unless @ldap.bind
|
|
16
|
+
end
|
|
17
|
+
@options[:enable_db_auth] = true unless @options[:enable_ldap_auth]
|
|
18
|
+
User.ensure_admin_exists!
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
##
|
|
22
|
+
# Is this user manager using ldap?
|
|
23
|
+
def using_ldap?
|
|
24
|
+
@options[:enable_ldap_auth]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
##
|
|
28
|
+
# Is the user manager using ldap?
|
|
29
|
+
def self.using_ldap?
|
|
30
|
+
default.using_ldap?
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
##
|
|
34
|
+
# Is this user manager using the db?
|
|
35
|
+
def using_db?
|
|
36
|
+
@options[:enable_db_auth]
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
##
|
|
40
|
+
# Is the user manager using the db?
|
|
41
|
+
def self.using_db?
|
|
42
|
+
default.using_db?
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
##
|
|
46
|
+
# Gets the first authentication source for this user manager.
|
|
47
|
+
def primary_source
|
|
48
|
+
return :ldap if using_ldap? && !using_db?
|
|
49
|
+
return :db if using_db? && !using_ldap?
|
|
50
|
+
|
|
51
|
+
source = @options[:primary_source]
|
|
52
|
+
source = source.to_sym if source.is_a?(String)
|
|
53
|
+
|
|
54
|
+
return source if [:ldap, :db].include?(source)
|
|
55
|
+
|
|
56
|
+
return :ldap if using_ldap?
|
|
57
|
+
|
|
58
|
+
:db
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
##
|
|
62
|
+
# Gets the first authentication source for the user manager.
|
|
63
|
+
def self.primary_source
|
|
64
|
+
default.primary_source
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
##
|
|
68
|
+
# Attempts to authenticate the user and returns the model on success.
|
|
69
|
+
def authenticate(email, password, client_ip)
|
|
70
|
+
return nil unless email && BarkestCore::EmailTester.valid_email?(email, false)
|
|
71
|
+
|
|
72
|
+
email = email.downcase
|
|
73
|
+
|
|
74
|
+
sources.each do |source|
|
|
75
|
+
if source == :ldap
|
|
76
|
+
entry = @ldap.search(filter: "(&(objectClass=user)(mail=#{email}))")
|
|
77
|
+
if entry && entry.count == 1 # we found a match.
|
|
78
|
+
user = User.find_by(email: email, ldap: true)
|
|
79
|
+
|
|
80
|
+
# make sure it authenticates correctly.
|
|
81
|
+
entry = @ldap.bind_as(filter: "(&(objectClass=user)(mail=#{email}))", password: password)
|
|
82
|
+
|
|
83
|
+
# do not allow authenticating against the DB now.
|
|
84
|
+
unless entry && entry.count == 1
|
|
85
|
+
add_failure_to user || email, '(LDAP) failed to authenticate', client_ip
|
|
86
|
+
return nil
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# load the user and return.
|
|
90
|
+
user = load_ldap_user(entry.first, true, client_ip)
|
|
91
|
+
unless user.enabled?
|
|
92
|
+
add_failure_to user, '(LDAP) account disabled', client_ip
|
|
93
|
+
return nil
|
|
94
|
+
end
|
|
95
|
+
add_success_to user, '(LDAP)', client_ip
|
|
96
|
+
return user
|
|
97
|
+
end
|
|
98
|
+
else
|
|
99
|
+
user = User.find_by(email: email)
|
|
100
|
+
if user
|
|
101
|
+
# user must be enabled, cannot be LDAP, and the password must match.
|
|
102
|
+
if user.ldap?
|
|
103
|
+
add_failure_to user, '(DB) cannot authenticate LDAP user', client_ip
|
|
104
|
+
return nil
|
|
105
|
+
end
|
|
106
|
+
unless user.enabled?
|
|
107
|
+
add_failure_to user, '(DB) account disabled', client_ip
|
|
108
|
+
return nil
|
|
109
|
+
end
|
|
110
|
+
if user.authenticate(password)
|
|
111
|
+
add_success_to user, '(DB)', client_ip
|
|
112
|
+
return user
|
|
113
|
+
else
|
|
114
|
+
add_failure_to user, '(DB) invalid password', client_ip
|
|
115
|
+
return nil
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
add_failure_to email, 'invalid email', client_ip
|
|
121
|
+
nil
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
##
|
|
125
|
+
# Attempts to authenticate the user and returns the model on success.
|
|
126
|
+
def self.authenticate(email, password, client_ip)
|
|
127
|
+
default.authenticate email, password, client_ip
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
##
|
|
131
|
+
# Should valid ldap users be auto-activated on first login?
|
|
132
|
+
def auto_activate_ldap?
|
|
133
|
+
@options[:ldap_auto_activate]
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
##
|
|
137
|
+
# Should valid ldap users be auto-activated on first login?
|
|
138
|
+
def self.auto_activate_ldap?
|
|
139
|
+
default.auto_activate_ldap?
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
##
|
|
143
|
+
# Gets the list of ldap groups that map to system administrators.
|
|
144
|
+
def ldap_system_admin_groups
|
|
145
|
+
@ldap_system_admin_groups ||=
|
|
146
|
+
begin
|
|
147
|
+
val = @options[:ldap_system_admin_groups]
|
|
148
|
+
val.blank? ? [] : val.strip.gsub(',', ';').split(';').map{|v| v.strip.upcase}
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
##
|
|
153
|
+
# Gets the list of ldap groups that map to system administrators.
|
|
154
|
+
def self.ldap_system_admin_groups
|
|
155
|
+
default.ldap_system_admin_groups
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
private
|
|
159
|
+
|
|
160
|
+
def purge_old_history_for(user, max_months = 2)
|
|
161
|
+
user.login_histories.where('"user_login_histories"."created_at" <= ?', Time.zone.now - max_months.months).delete_all
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def add_failure_to(user, message, client_ip)
|
|
165
|
+
Rails.logger.info "LOGIN(#{user}) FAILURE FROM #{client_ip}: #{message}"
|
|
166
|
+
history_length = 2
|
|
167
|
+
unless user.is_a?(User)
|
|
168
|
+
message = "[email: #{user}] #{message}"
|
|
169
|
+
user = User.anonymous
|
|
170
|
+
history_length = 6
|
|
171
|
+
end
|
|
172
|
+
purge_old_history_for user, history_length
|
|
173
|
+
user.login_histories.create(ip_address: client_ip, successful: false, message: message)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def add_success_to(user, message, client_ip)
|
|
177
|
+
Rails.logger.debug "LOGIN(#{user}) SUCCESS FROM #{client_ip}: #{message}"
|
|
178
|
+
purge_old_history_for user
|
|
179
|
+
user.login_histories.create(ip_address: client_ip, successful: true, message: message)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def sources
|
|
183
|
+
@sources ||=
|
|
184
|
+
if using_ldap? && using_db?
|
|
185
|
+
if primary_source == :db
|
|
186
|
+
[ :db, :ldap ]
|
|
187
|
+
else
|
|
188
|
+
[ :ldap, :db ]
|
|
189
|
+
end
|
|
190
|
+
elsif using_ldap?
|
|
191
|
+
[ :ldap ]
|
|
192
|
+
else
|
|
193
|
+
[ :db ]
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def self.default
|
|
198
|
+
@default ||= UserManager.new(BarkestCore.auth_config)
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# Decode a binary SID into the common string form.
|
|
202
|
+
# Used on AD servers to locate the primary group membership.
|
|
203
|
+
# See http://blogs.msdn.com/b/oldnewthing/archive/2004/03/15/89753.aspx
|
|
204
|
+
def self.decode_sid(binary_sid)
|
|
205
|
+
|
|
206
|
+
# only support SID revision 1
|
|
207
|
+
return false unless binary_sid && binary_sid[0].ord == 1
|
|
208
|
+
|
|
209
|
+
ret = 'S-1-'
|
|
210
|
+
|
|
211
|
+
dashes_remaining = binary_sid[1].ord
|
|
212
|
+
|
|
213
|
+
# remove first 2 bytes and continue.
|
|
214
|
+
binary_sid = binary_sid[2..-1]
|
|
215
|
+
|
|
216
|
+
# first group is 48-bit big-endian.
|
|
217
|
+
i = 0
|
|
218
|
+
binary_sid[0..5].chars.each do |b|
|
|
219
|
+
i = (i * 256) + b.ord
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
ret <<= i.to_s
|
|
223
|
+
|
|
224
|
+
# remaining groups are 32-bit little-endian.
|
|
225
|
+
binary_sid = binary_sid[6..-1]
|
|
226
|
+
while dashes_remaining > 0
|
|
227
|
+
i = 0
|
|
228
|
+
binary_sid[0..3].reverse.chars.each do |b|
|
|
229
|
+
i = (i * 256) + b.ord
|
|
230
|
+
end
|
|
231
|
+
ret <<= "-#{i}"
|
|
232
|
+
dashes_remaining -= 1
|
|
233
|
+
binary_sid = binary_sid[4..-1]
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
ret
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
def get_ldap_connection
|
|
241
|
+
ldap = Net::LDAP.new(host: @options[:ldap_host], port: @options[:ldap_port], base: @options[:ldap_base_dn])
|
|
242
|
+
ssl = @options[:ldap_ssl]
|
|
243
|
+
ssl = ssl.to_s.downcase
|
|
244
|
+
ssl = true if ssl == 'true'
|
|
245
|
+
ssl = false if ssl == 'false' || ssl == '' || ssl == 'nil'
|
|
246
|
+
ssl = ssl.to_sym if ssl.is_a?(String)
|
|
247
|
+
|
|
248
|
+
if ssl
|
|
249
|
+
if ssl == :simple_tls
|
|
250
|
+
ldap.encryption method: :simple_tls
|
|
251
|
+
elsif ssl == :start_tls
|
|
252
|
+
ldap.encryption method: :start_tls
|
|
253
|
+
else
|
|
254
|
+
if @options[:ldap_port] == 389
|
|
255
|
+
ldap.encryption method: :start_tls
|
|
256
|
+
else
|
|
257
|
+
ldap.encryption method: :simple_tls
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
if @options[:ldap_browse_user]
|
|
263
|
+
ldap.authenticate @options[:ldap_browse_user], @options[:ldap_browse_password]
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
ldap
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
def attrib_val(entry, attr)
|
|
270
|
+
return nil unless entry.attribute_names.include?(attr)
|
|
271
|
+
val = entry[attr]
|
|
272
|
+
val = val.first if val && val.respond_to?(:first)
|
|
273
|
+
val
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
def first_attrib_val(entry, *attr)
|
|
277
|
+
attr.each do |a|
|
|
278
|
+
v = attrib_val(entry, a)
|
|
279
|
+
return v if v
|
|
280
|
+
end
|
|
281
|
+
nil
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
def group_to_groups(group_entry, existing_groups)
|
|
285
|
+
return [] unless group_entry
|
|
286
|
+
|
|
287
|
+
ret = []
|
|
288
|
+
|
|
289
|
+
# get the group name.
|
|
290
|
+
|
|
291
|
+
name = first_attrib_val(group_entry, :samaccountname, :name, :cn)
|
|
292
|
+
|
|
293
|
+
return [] unless name
|
|
294
|
+
|
|
295
|
+
name.upcase!
|
|
296
|
+
|
|
297
|
+
# do not duplicate entries. this will also prevent the possibility of infinite recursion.
|
|
298
|
+
unless existing_groups.index { |x| x == name } || ret.index { |x| x == name }
|
|
299
|
+
|
|
300
|
+
# add this group.
|
|
301
|
+
ret <<= name
|
|
302
|
+
|
|
303
|
+
# if the group belongs to parent groups, add them as well.
|
|
304
|
+
if group_entry[:memberof] && group_entry[:memberof].respond_to?('each')
|
|
305
|
+
group_entry[:memberof].each do |dn|
|
|
306
|
+
parent_entry = @ldap.search(base: dn).first
|
|
307
|
+
ret += group_to_groups(parent_entry, ret + existing_groups)
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
ret
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
def load_ldap_user(entry, update_permissions = false, client_ip = '0.0.0.0')
|
|
316
|
+
|
|
317
|
+
# email is our unique identifier
|
|
318
|
+
email = attrib_val(entry, :mail)
|
|
319
|
+
return nil unless email
|
|
320
|
+
email.downcase!
|
|
321
|
+
|
|
322
|
+
# grab the SID and find the user.
|
|
323
|
+
ret = User.find_by(email: email)
|
|
324
|
+
pwd = SecureRandom.urlsafe_base64(53) # should generate a 71 character string.
|
|
325
|
+
# max supported by has_secure_password is 72 characters.
|
|
326
|
+
|
|
327
|
+
if ret
|
|
328
|
+
# set ldap flag and change to random password.
|
|
329
|
+
ret.ldap = true
|
|
330
|
+
ret.password = ret.password_confirmation = pwd
|
|
331
|
+
else
|
|
332
|
+
# create new user with random password.
|
|
333
|
+
ret = User.create!(
|
|
334
|
+
name: email,
|
|
335
|
+
email: email,
|
|
336
|
+
password: pwd,
|
|
337
|
+
password_confirmation: pwd,
|
|
338
|
+
enabled: true
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
if auto_activate_ldap?
|
|
342
|
+
ret.activate
|
|
343
|
+
else
|
|
344
|
+
ret.send_activation_email(client_ip)
|
|
345
|
+
end
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
# update the user attributes in the database.
|
|
349
|
+
ret.name = first_attrib_val(entry, :displayname, :givenname, :name, :cn)
|
|
350
|
+
ret.ldap = true
|
|
351
|
+
ret.save!
|
|
352
|
+
|
|
353
|
+
if update_permissions
|
|
354
|
+
# now we need the user group memberships from ldap
|
|
355
|
+
# once we get those, we can translate them over.
|
|
356
|
+
groups = []
|
|
357
|
+
entry[:memberof].each do |dn|
|
|
358
|
+
# load the group and get the group name (always in uppercase)
|
|
359
|
+
group_entry = @ldap.search(base: dn).first
|
|
360
|
+
groups += group_to_groups(group_entry, groups)
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
# there may be one missing group still, the default group is not included in the 'memberOf' attribute.
|
|
364
|
+
if (group_rid = attrib_val(entry, :primarygroupid))
|
|
365
|
+
# the primary group id is the relative ID within the domain SID for the group.
|
|
366
|
+
# so we'll get the domain SID from the user SID and append the group RID.
|
|
367
|
+
user_sid = UserManager.decode_sid(attrib_val(entry, :objectsid))
|
|
368
|
+
if user_sid
|
|
369
|
+
domain_sid = user_sid.rpartition('-')[0]
|
|
370
|
+
group_sid = "#{domain_sid}-#{group_rid}"
|
|
371
|
+
|
|
372
|
+
# the search takes the SID in string form, not in binary form (like in other places).
|
|
373
|
+
group_entry = @ldap.search(filter: "(&(objectClass=group)(objectSID=#{group_sid}))")
|
|
374
|
+
|
|
375
|
+
# did we locate the group?
|
|
376
|
+
if group_entry && group_entry.count == 1
|
|
377
|
+
groups += group_to_groups(group_entry.first, groups)
|
|
378
|
+
else
|
|
379
|
+
Rails.logger.warn "WARNING: Failed to locate group with SID=#{group_sid}"
|
|
380
|
+
end
|
|
381
|
+
end
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
# so now 'groups' contains a list of every ldap group the user belongs to.
|
|
385
|
+
ret.system_admin = false
|
|
386
|
+
ldap_system_admin_groups.each do |group|
|
|
387
|
+
ret.system_admin = true if groups.include?(group)
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
access_groups = []
|
|
391
|
+
groups.each do |group|
|
|
392
|
+
access_group = AccessGroup.find_by(name: group)
|
|
393
|
+
access_groups << access_group.group if access_group && !access_groups.include?(access_group.group)
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
ret.groups = access_groups
|
|
397
|
+
ret.save!
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
ret
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
end
|
|
404
|
+
end
|