From 402eddca821037945832fb016e53b597ddb90d8a Mon Sep 17 00:00:00 2001 From: baarkerlounger <5101747+baarkerlounger@users.noreply.github.com> Date: Thu, 26 May 2022 17:02:46 +0100 Subject: [PATCH] Remove active admin (#611) * Remove stuff * Remove ActiveAdmin from Gem file * Remove routes and table * Rubocop * Remove active admin from webpack config * Remove JQuery from webpack * Remove remaining spec references * Remove js packages * Schema --- Gemfile | 2 - Gemfile.lock | 44 --- app/admin/admin_users.rb | 37 -- app/admin/case_logs.rb | 20 -- app/admin/dashboard.rb | 32 -- app/admin/organisations.rb | 31 -- app/admin/users.rb | 42 --- app/concerns/.keep | 0 app/concerns/admin/paper_trail.rb | 15 - app/controllers/auth/passwords_controller.rb | 6 +- app/controllers/auth/sessions_controller.rb | 20 +- app/frontend/active_admin.js | 7 - app/frontend/styles/active_admin.scss | 17 - app/models/admin_user.rb | 36 -- config/initializers/active_admin.rb | 339 ------------------ config/routes.rb | 25 -- db/migrate/20220525130518_drop_admin_users.rb | 36 ++ db/schema.rb | 31 +- package.json | 1 - .../admin/admin_users_controller_spec.rb | 78 ---- .../admin/case_logs_controller_spec.rb | 92 ----- .../admin/dashboard_controller_spec.rb | 44 --- .../admin/organisations_controller_spec.rb | 78 ---- .../admin/users_controller_spec.rb | 97 ----- spec/features/admin_panel_spec.rb | 162 --------- spec/features/auth/user_lockout_spec.rb | 50 --- spec/models/admin_user_spec.rb | 84 ----- .../auth/passwords_controller_spec.rb | 72 ---- spec/requests/rack_attack_spec.rb | 41 --- webpack.config.js | 10 - yarn.lock | 26 -- 31 files changed, 44 insertions(+), 1531 deletions(-) delete mode 100644 app/admin/admin_users.rb delete mode 100644 app/admin/case_logs.rb delete mode 100644 app/admin/dashboard.rb delete mode 100644 app/admin/organisations.rb delete mode 100644 app/admin/users.rb create mode 100644 app/concerns/.keep delete mode 100644 app/concerns/admin/paper_trail.rb delete mode 100644 app/frontend/active_admin.js delete mode 100644 app/frontend/styles/active_admin.scss delete mode 100644 app/models/admin_user.rb delete mode 100644 config/initializers/active_admin.rb create mode 100644 db/migrate/20220525130518_drop_admin_users.rb delete mode 100644 spec/controllers/admin/admin_users_controller_spec.rb delete mode 100644 spec/controllers/admin/case_logs_controller_spec.rb delete mode 100644 spec/controllers/admin/dashboard_controller_spec.rb delete mode 100644 spec/controllers/admin/organisations_controller_spec.rb delete mode 100644 spec/controllers/admin/users_controller_spec.rb delete mode 100644 spec/features/admin_panel_spec.rb delete mode 100644 spec/models/admin_user_spec.rb diff --git a/Gemfile b/Gemfile index 35abd8d23..6e48d0262 100644 --- a/Gemfile +++ b/Gemfile @@ -27,8 +27,6 @@ gem "govuk_markdown" gem "notifications-ruby-client" # A modest javascript framework for the html you already have gem "stimulus-rails" -# Administration framework -gem "activeadmin" # Admin charts gem "chartkick" # Spreadsheet parsing diff --git a/Gemfile.lock b/Gemfile.lock index b412e0a82..bf8e64d2c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -69,15 +69,6 @@ GEM erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activeadmin (2.12.0) - arbre (~> 1.2, >= 1.2.1) - formtastic (>= 3.1, < 5.0) - formtastic_i18n (~> 0.4) - inherited_resources (~> 1.7) - jquery-rails (~> 4.2) - kaminari (~> 1.0, >= 1.2.1) - railties (>= 6.0, < 7.1) - ransack (>= 2.1.1, < 4) activejob (7.0.2.4) activesupport (= 7.0.2.4) globalid (>= 0.3.6) @@ -100,9 +91,6 @@ GEM tzinfo (~> 2.0) addressable (2.8.0) public_suffix (>= 2.0.2, < 5.0) - arbre (1.5.0) - activesupport (>= 3.0.0, < 7.1) - ruby2_keywords (>= 0.0.2, < 1.0) ast (2.4.2) aws-eventstream (1.2.0) aws-partitions (1.584.0) @@ -183,9 +171,6 @@ GEM factory_bot (~> 6.2.0) railties (>= 5.0.0) ffi (1.15.5) - formtastic (4.0.0) - actionpack (>= 5.2.0) - formtastic_i18n (0.7.0) globalid (1.0.0) activesupport (>= 5.0) govuk-components (3.0.3) @@ -200,41 +185,17 @@ GEM govuk_markdown (1.0.0) activesupport redcarpet - has_scope (0.8.0) - actionpack (>= 5.2) - activesupport (>= 5.2) hashdiff (1.0.1) html_tokenizer (0.0.7) i18n (1.10.0) concurrent-ruby (~> 1.0) - inherited_resources (1.13.1) - actionpack (>= 5.2, < 7.1) - has_scope (~> 0.6) - railties (>= 5.2, < 7.1) - responders (>= 2, < 4) iniparse (1.5.0) jmespath (1.6.1) - jquery-rails (4.4.0) - rails-dom-testing (>= 1, < 3) - railties (>= 4.2.0) - thor (>= 0.14, < 2.0) jsbundling-rails (1.0.2) railties (>= 6.0.0) json-schema (3.0.0) addressable (>= 2.8) jwt (2.3.0) - kaminari (1.2.2) - activesupport (>= 4.1.0) - kaminari-actionview (= 1.2.2) - kaminari-activerecord (= 1.2.2) - kaminari-core (= 1.2.2) - kaminari-actionview (1.2.2) - actionview - kaminari-core (= 1.2.2) - kaminari-activerecord (1.2.2) - activerecord - kaminari-core (= 1.2.2) - kaminari-core (1.2.2) listen (3.7.1) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) @@ -342,10 +303,6 @@ GEM rainbow (3.1.1) rake (13.0.6) randexp (0.1.7) - ransack (3.1.0) - activerecord (>= 6.0.4) - activesupport (>= 6.0.4) - i18n rb-fsevent (0.11.1) rb-inotify (0.10.1) ffi (~> 1.0) @@ -468,7 +425,6 @@ PLATFORMS x86_64-linux DEPENDENCIES - activeadmin aws-sdk-s3 bootsnap (>= 1.4.4) bundler-audit diff --git a/app/admin/admin_users.rb b/app/admin/admin_users.rb deleted file mode 100644 index e161e0202..000000000 --- a/app/admin/admin_users.rb +++ /dev/null @@ -1,37 +0,0 @@ -ActiveAdmin.register AdminUser do - permit_params :email, :phone, :password, :password_confirmation - - controller do - def update_resource(object, attributes) - update_method = attributes.first[:password].present? ? :update : :update_without_password - object.send(update_method, *attributes) - end - end - - index do - selectable_column - id_column - column :email - column "Phone Number", :phone - column :current_sign_in_at - column :sign_in_count - column :created_at - actions - end - - filter :email - filter :phone - filter :current_sign_in_at - filter :sign_in_count - filter :created_at - - form do |f| - f.inputs do - f.input :email - f.input :phone - f.input :password - f.input :password_confirmation - end - f.actions - end -end diff --git a/app/admin/case_logs.rb b/app/admin/case_logs.rb deleted file mode 100644 index 389830a16..000000000 --- a/app/admin/case_logs.rb +++ /dev/null @@ -1,20 +0,0 @@ -ActiveAdmin.register CaseLog do - # See permitted parameters documentation: - # https://github.com/activeadmin/activeadmin/blob/master/docs/2-resource-customization.md#setting-up-strong-parameters - permit_params do - CaseLog.editable_fields - end - - index do - selectable_column - id_column - column :created_at - column :updated_at - column :status - column :tenant_code - column :postcode_full - column :owning_organisation - column :managing_organisation - actions - end -end diff --git a/app/admin/dashboard.rb b/app/admin/dashboard.rb deleted file mode 100644 index 579f6f487..000000000 --- a/app/admin/dashboard.rb +++ /dev/null @@ -1,32 +0,0 @@ -ActiveAdmin.register_page "Dashboard" do - menu priority: 1, label: proc { I18n.t("active_admin.dashboard") } - - content title: proc { I18n.t("active_admin.dashboard") } do - columns do - column do - panel "Recent logs" do - table_for CaseLog.order(updated_at: :desc).limit(10) do - column :id - column :created_at - column :updated_at - column :status - column :tenant_code - column :postcode_full - end - end - end - - column do - panel "Total logs in progress" do - para CaseLog.in_progress.size - end - panel "Total logs completed" do - para CaseLog.completed.size - end - panel "Total logs completed" do - pie_chart CaseLog.group(:status).size - end - end - end - end -end diff --git a/app/admin/organisations.rb b/app/admin/organisations.rb deleted file mode 100644 index a9e7fb17d..000000000 --- a/app/admin/organisations.rb +++ /dev/null @@ -1,31 +0,0 @@ -ActiveAdmin.register Organisation do - permit_params do - permitted = %i[name - phone - provider_type - address_line1 - address_line2 - postcode - local_authorities - holds_own_stock - other_stock_owners - managing_agents] - permitted - end - - index do - selectable_column - id_column - column :name - column "Org type", :provider_type - column "Address Line 1", :address_line1 - column "Address Line 2", :address_line2 - column :postcode - column "Phone Number", :phone - column :local_authorities - column :holds_own_stock - column :other_stock_owners - column :managing_agents - actions - end -end diff --git a/app/admin/users.rb b/app/admin/users.rb deleted file mode 100644 index 59a235b99..000000000 --- a/app/admin/users.rb +++ /dev/null @@ -1,42 +0,0 @@ -ActiveAdmin.register User do - permit_params :name, :email, :password, :password_confirmation, :organisation_id, :role - - controller do - def update_resource(object, attributes) - update_method = attributes.first[:password].present? ? :update : :update_without_password - object.send(update_method, *attributes) - end - end - - index do - selectable_column - id_column - column :name - column :email - column :organisation - column(:role) { |u| u.role.to_s.humanize } - column :current_sign_in_at - column :sign_in_count - column :created_at - actions - end - - filter :email - filter :name - filter :organisation - filter :current_sign_in_at - filter :sign_in_count - filter :created_at - - form do |f| - f.inputs do - f.input :name - f.input :email - f.input :password - f.input :password_confirmation - f.input :organisation - f.input :role - end - f.actions - end -end diff --git a/app/concerns/.keep b/app/concerns/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/app/concerns/admin/paper_trail.rb b/app/concerns/admin/paper_trail.rb deleted file mode 100644 index 5558d465b..000000000 --- a/app/concerns/admin/paper_trail.rb +++ /dev/null @@ -1,15 +0,0 @@ -module Admin - module PaperTrail - extend ActiveSupport::Concern - - included do - before_action :set_paper_trail_whodunnit - end - - protected - - def user_for_paper_trail - current_admin_user - end - end -end diff --git a/app/controllers/auth/passwords_controller.rb b/app/controllers/auth/passwords_controller.rb index c26529157..e6b1f3a49 100644 --- a/app/controllers/auth/passwords_controller.rb +++ b/app/controllers/auth/passwords_controller.rb @@ -62,12 +62,8 @@ protected resource.need_two_factor_authentication?(request) ? :updated_2FA : :updated end - def resource_class_name - resource_class.name.underscore - end - def after_sending_reset_password_instructions_path_for(_resource) - account_password_reset_confirmation_path(email: params.dig(resource_class_name, "email")) + account_password_reset_confirmation_path(email: params.dig("user", "email")) end def after_resetting_password_path_for(resource) diff --git a/app/controllers/auth/sessions_controller.rb b/app/controllers/auth/sessions_controller.rb index ad65de5e0..1180a51de 100644 --- a/app/controllers/auth/sessions_controller.rb +++ b/app/controllers/auth/sessions_controller.rb @@ -2,13 +2,13 @@ class Auth::SessionsController < Devise::SessionsController include Helpers::Email def create - self.resource = resource_class.new - if params.dig(resource_class_name, "email").empty? + self.resource = User.new + if params.dig("user", "email").empty? resource.errors.add :email, "Enter an email address" - elsif !email_valid?(params.dig(resource_class_name, "email")) + elsif !email_valid?(params.dig("user", "email")) resource.errors.add :email, "Enter an email address in the correct format, like name@example.com" end - if params.dig(resource_class_name, "password").empty? + if params.dig("user", "password").empty? resource.errors.add :password, "Enter a password" end if resource.errors.present? @@ -20,19 +20,11 @@ class Auth::SessionsController < Devise::SessionsController private - def resource_class - request.path.include?("admin") ? AdminUser : User - end - - def resource_class_name - resource_class.name.underscore - end - def after_sign_in_path_for(resource) if resource.need_two_factor_authentication?(request) - send("#{resource_name}_two_factor_authentication_path") + user_two_factor_authentication_path else - params.dig(resource_class_name, "start").present? ? case_logs_path : super + params.dig("user", "start").present? ? case_logs_path : super end end end diff --git a/app/frontend/active_admin.js b/app/frontend/active_admin.js deleted file mode 100644 index 95c03bbb9..000000000 --- a/app/frontend/active_admin.js +++ /dev/null @@ -1,7 +0,0 @@ -// Load Active Admin's styles into Webpacker, -// see `active_admin.scss` for customization. -import "./styles/active_admin.scss"; - -import "@activeadmin/activeadmin"; - -import "chartkick/chart.js" diff --git a/app/frontend/styles/active_admin.scss b/app/frontend/styles/active_admin.scss deleted file mode 100644 index 66b7017f9..000000000 --- a/app/frontend/styles/active_admin.scss +++ /dev/null @@ -1,17 +0,0 @@ -// Sass variable overrides must be declared before loading up Active Admin's styles. -// -// To view the variables that Active Admin provides, take a look at -// `app/assets/stylesheets/active_admin/mixins/_variables.scss` in the -// Active Admin source. -// -// For example, to change the sidebar width: -// $sidebar-width: 242px; - -// Active Admin's got SASS! -@import "@activeadmin/activeadmin/src/scss/mixins"; -@import "@activeadmin/activeadmin/src/scss/base"; - -// Overriding any non-variable Sass must be done after the fact. -// For example, to change the default status-tag color: -// -// .status_tag { background: #6090DB; } diff --git a/app/models/admin_user.rb b/app/models/admin_user.rb deleted file mode 100644 index 7fe671e05..000000000 --- a/app/models/admin_user.rb +++ /dev/null @@ -1,36 +0,0 @@ -class AdminUser < ApplicationRecord - # Include default devise modules. Others available are: - # :confirmable, :timeoutable, :omniauthable - devise :two_factor_authenticatable, :database_authenticatable, :recoverable, - :rememberable, :validatable, :trackable, :lockable - - has_one_time_password(encrypted: true) - - has_paper_trail ignore: %w[last_sign_in_at - current_sign_in_at - current_sign_in_ip - last_sign_in_ip - failed_attempts - unlock_token - locked_at - reset_password_token - reset_password_sent_at - remember_created_at - sign_in_count - updated_at] - - validates :phone, presence: true, numericality: true - - MFA_TEMPLATE_ID = "6bdf5ee1-8e01-4be1-b1f9-747061d8a24c".freeze - RESET_PASSWORD_TEMPLATE_ID = "fbb2d415-b9b1-4507-ba0a-6e542fa3504d".freeze - - def send_two_factor_authentication_code(code) - template_id = MFA_TEMPLATE_ID - personalisation = { otp: code } - DeviseNotifyMailer.new.send_email(email, template_id, personalisation) - end - - def reset_password_notify_template - RESET_PASSWORD_TEMPLATE_ID - end -end diff --git a/config/initializers/active_admin.rb b/config/initializers/active_admin.rb deleted file mode 100644 index ec86c8caf..000000000 --- a/config/initializers/active_admin.rb +++ /dev/null @@ -1,339 +0,0 @@ -ActiveAdmin.setup do |config| - # == Site Title - # - # Set the title that is displayed on the main layout - # for each of the active admin pages. - # - config.site_title = "DLUHC CORE" - - # Set the link url for the title. For example, to take - # users to your main site. Defaults to no link. - # - # config.site_title_link = "/" - - # Set an optional image to be displayed for the header - # instead of a string (overrides :site_title) - # - # Note: Aim for an image that's 21px high so it fits in the header. - # - # config.site_title_image = "logo.png" - - # == Default Namespace - # - # Set the default namespace each administration resource - # will be added to. - # - # eg: - # config.default_namespace = :hello_world - # - # This will create resources in the HelloWorld module and - # will namespace routes to /hello_world/* - # - # To set no namespace by default, use: - # config.default_namespace = false - # - # Default: - # config.default_namespace = :admin - # - # You can customize the settings for each namespace by using - # a namespace block. For example, to change the site title - # within a namespace: - # - # config.namespace :admin do |admin| - # admin.site_title = "Custom Admin Title" - # end - # - # This will ONLY change the title for the admin section. Other - # namespaces will continue to use the main "site_title" configuration. - - # == User Authentication - # - # Active Admin will automatically call an authentication - # method in a before filter of all controller actions to - # ensure that there is a currently logged in admin user. - # - # This setting changes the method which Active Admin calls - # within the application controller. - config.authentication_method = :authenticate_admin_user! - - # == User Authorization - # - # Active Admin will automatically call an authorization - # method in a before filter of all controller actions to - # ensure that there is a user with proper rights. You can use - # CanCanAdapter or make your own. Please refer to documentation. - # config.authorization_adapter = ActiveAdmin::CanCanAdapter - - # In case you prefer Pundit over other solutions you can here pass - # the name of default policy class. This policy will be used in every - # case when Pundit is unable to find suitable policy. - # config.pundit_default_policy = "MyDefaultPunditPolicy" - - # If you wish to maintain a separate set of Pundit policies for admin - # resources, you may set a namespace here that Pundit will search - # within when looking for a resource's policy. - # config.pundit_policy_namespace = :admin - - # You can customize your CanCan Ability class name here. - # config.cancan_ability_class = "Ability" - - # You can specify a method to be called on unauthorized access. - # This is necessary in order to prevent a redirect loop which happens - # because, by default, user gets redirected to Dashboard. If user - # doesn't have access to Dashboard, he'll end up in a redirect loop. - # Method provided here should be defined in application_controller.rb. - # config.on_unauthorized_access = :access_denied - - # == Current User - # - # Active Admin will associate actions with the current - # user performing them. - # - # This setting changes the method which Active Admin calls - # (within the application controller) to return the currently logged in user. - config.current_user_method = :current_admin_user - - # == Logging Out - # - # Active Admin displays a logout link on each screen. These - # settings configure the location and method used for the link. - # - # This setting changes the path where the link points to. If it's - # a string, the strings is used as the path. If it's a Symbol, we - # will call the method to return the path. - # - # Default: - config.logout_link_path = :destroy_admin_user_session_path - - # This setting changes the http method used when rendering the - # link. For example :get, :delete, :put, etc.. - # - # Default: - # config.logout_link_method = :get - - # == Root - # - # Set the action to call for the root path. You can set different - # roots for each namespace. - # - # Default: - # config.root_to = 'dashboard#index' - - # == Admin Comments - # - # This allows your users to comment on any resource registered with Active Admin. - # - # You can completely disable comments: - config.comments = false - # - # You can change the name under which comments are registered: - # config.comments_registration_name = 'AdminComment' - # - # You can change the order for the comments and you can change the column - # to be used for ordering: - # config.comments_order = 'created_at ASC' - # - # You can disable the menu item for the comments index page: - # config.comments_menu = false - # - # You can customize the comment menu: - # config.comments_menu = { parent: 'Admin', priority: 1 } - - # == Batch Actions - # - # Enable and disable Batch Actions - # - config.batch_actions = true - - # == Controller Filters - # - # You can add before, after and around filters to all of your - # Active Admin resources and pages from here. - # - # config.before_action :do_something_awesome - - # == Attribute Filters - # - # You can exclude possibly sensitive model attributes from being displayed, - # added to forms, or exported by default by ActiveAdmin - # - config.filter_attributes = %i[encrypted_password password password_confirmation] - - # == Localize Date/Time Format - # - # Set the localize format to display dates and times. - # To understand how to localize your app with I18n, read more at - # https://guides.rubyonrails.org/i18n.html - # - # You can run `bin/rails runner 'puts I18n.t("date.formats")'` to see the - # available formats in your application. - # - config.localize_format = :long - - # == Setting a Favicon - # - # config.favicon = 'favicon.ico' - - # == Meta Tags - # - # Add additional meta tags to the head element of active admin pages. - # - # Add tags to all pages logged in users see: - # config.meta_tags = { author: 'My Company' } - - # By default, sign up/sign in/recover password pages are excluded - # from showing up in search engine results by adding a robots meta - # tag. You can reset the hash of meta tags included in logged out - # pages: - # config.meta_tags_for_logged_out_pages = {} - - # == Removing Breadcrumbs - # - # Breadcrumbs are enabled by default. You can customize them for individual - # resources or you can disable them globally from here. - # - # config.breadcrumb = false - - # == Create Another Checkbox - # - # Create another checkbox is disabled by default. You can customize it for individual - # resources or you can enable them globally from here. - # - # config.create_another = true - - # == Register Stylesheets & Javascripts - # - # We recommend using the built in Active Admin layout and loading - # up your own stylesheets / javascripts to customize the look - # and feel. - # - # To load a stylesheet: - # config.register_stylesheet 'my_stylesheet.css' - # - # You can provide an options hash for more control, which is passed along to stylesheet_link_tag(): - # config.register_stylesheet 'my_print_stylesheet.css', media: :print - # - # To load a javascript file: - # config.register_javascript 'my_javascript.js' - - # == CSV options - # - # Set the CSV builder separator - # config.csv_options = { col_sep: ';' } - # - # Force the use of quotes - # config.csv_options = { force_quotes: true } - - # == Menu System - # - # You can add a navigation menu to be used in your application, or configure a provided menu - # - # To change the default utility navigation to show a link to your website & a logout btn - # - # config.namespace :admin do |admin| - # admin.build_menu :utility_navigation do |menu| - # menu.add label: "My Great Website", url: "http://www.mygreatwebsite.com", html_options: { target: :blank } - # admin.add_logout_button_to_menu menu - # end - # end - # - # If you wanted to add a static menu item to the default menu provided: - # - # config.namespace :admin do |admin| - # admin.build_menu :default do |menu| - # menu.add label: "My Great Website", url: "http://www.mygreatwebsite.com", html_options: { target: :blank } - # end - # end - - # == Download Links - # - # You can disable download links on resource listing pages, - # or customize the formats shown per namespace/globally - # - # To disable/customize for the :admin namespace: - # - # config.namespace :admin do |admin| - # - # # Disable the links entirely - # admin.download_links = false - # - # # Only show XML & PDF options - # admin.download_links = [:xml, :pdf] - # - # # Enable/disable the links based on block - # # (for example, with cancan) - # admin.download_links = proc { can?(:view_download_links) } - # - # end - - # == Pagination - # - # Pagination is enabled by default for all resources. - # You can control the default per page count for all resources here. - # - # config.default_per_page = 30 - # - # You can control the max per page count too. - # - # config.max_per_page = 10_000 - - # == Filters - # - # By default the index screen includes a "Filters" sidebar on the right - # hand side with a filter for each attribute of the registered model. - # You can enable or disable them for all resources here. - # - # config.filters = true - # - # By default the filters include associations in a select, which means - # that every record will be loaded for each association (up - # to the value of config.maximum_association_filter_arity). - # You can enabled or disable the inclusion - # of those filters by default here. - # - # config.include_default_association_filters = true - - # config.maximum_association_filter_arity = 256 # default value of :unlimited will change to 256 in a future version - # config.filter_columns_for_large_association = [ - # :display_name, - # :full_name, - # :name, - # :username, - # :login, - # :title, - # :email, - # ] - # config.filter_method_for_large_association = '_starts_with' - - # == Head - # - # You can add your own content to the site head like analytics. Make sure - # you only pass content you trust. - # - # config.head = ''.html_safe - - # == Footer - # - # By default, the footer shows the current Active Admin version. You can - # override the content of the footer here. - # - # config.footer = 'my custom footer text' - - # == Sorting - # - # By default ActiveAdmin::OrderClause is used for sorting logic - # You can inherit it with own class and inject it for all resources - # - # config.order_clause = MyOrderClause - - # == Webpacker - # - # By default, Active Admin uses Sprocket's asset pipeline. - # You can switch to using Webpacker here. - # - # config.use_webpacker = true -end - -Rails.application.config.after_initialize do - ActiveAdmin::BaseController.include Admin::PaperTrail -end diff --git a/config/routes.rb b/config/routes.rb index 33c9f0a9a..c70cb2525 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,28 +1,5 @@ # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html Rails.application.routes.draw do - devise_for :admin_users, { - path: :admin, - controllers: { - sessions: "auth/sessions", - passwords: "auth/passwords", - unlocks: "active_admin/devise/unlocks", - registrations: "active_admin/devise/registrations", - confirmations: "active_admin/devise/confirmations", - two_factor_authentication: "auth/two_factor_authentication", - }, - path_names: { - sign_in: "sign-in", - sign_out: "sign-out", - two_factor_authentication: "two-factor-authentication", - two_factor_authentication_resend_code: "resend-code", - }, - sign_out_via: %i[get], - } - - devise_scope :admin_user do - get "admin/two-factor-authentication/resend", to: "auth/two_factor_authentication#show_resend", as: "admin_user_two_factor_authentication_resend" - end - devise_for :users, { path: :account, controllers: { @@ -48,8 +25,6 @@ Rails.application.routes.draw do get "/health", to: ->(_) { [204, {}, [nil]] } - ActiveAdmin.routes(self) - root to: "start#index" get "/accessibility-statement", to: "content#accessibility_statement" diff --git a/db/migrate/20220525130518_drop_admin_users.rb b/db/migrate/20220525130518_drop_admin_users.rb new file mode 100644 index 000000000..bf96e23de --- /dev/null +++ b/db/migrate/20220525130518_drop_admin_users.rb @@ -0,0 +1,36 @@ +class DropAdminUsers < ActiveRecord::Migration[7.0] + def up + drop_table :admin_users + end + + def down + create_table "admin_users", force: :cascade do |t| + t.string "email", default: "", null: false + t.string "encrypted_password", default: "", null: false + t.string "reset_password_token" + t.datetime "reset_password_sent_at", precision: nil + t.datetime "remember_created_at", precision: nil + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.integer "second_factor_attempts_count", default: 0 + t.string "encrypted_otp_secret_key" + t.string "encrypted_otp_secret_key_iv" + t.string "encrypted_otp_secret_key_salt" + t.string "direct_otp" + t.datetime "direct_otp_sent_at", precision: nil + t.datetime "totp_timestamp", precision: nil + t.string "phone" + t.string "name" + t.integer "sign_in_count", default: 0, null: false + t.datetime "current_sign_in_at", precision: nil + t.datetime "last_sign_in_at", precision: nil + t.string "current_sign_in_ip" + t.string "last_sign_in_ip" + t.integer "failed_attempts", default: 0 + t.string "unlock_token" + t.datetime "locked_at", precision: nil + t.index %w[encrypted_otp_secret_key], name: "index_admin_users_on_encrypted_otp_secret_key", unique: true + t.index %w[unlock_token], name: "index_admin_users_on_unlock_token", unique: true + end + end +end diff --git a/db/schema.rb b/db/schema.rb index a2b94061b..47c6a6883 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,39 +10,10 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2022_05_23_150557) do +ActiveRecord::Schema[7.0].define(version: 2022_05_25_130518) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" - create_table "admin_users", force: :cascade do |t| - t.string "email", default: "", null: false - t.string "encrypted_password", default: "", null: false - t.string "reset_password_token" - t.datetime "reset_password_sent_at", precision: nil - t.datetime "remember_created_at", precision: nil - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.integer "second_factor_attempts_count", default: 0 - t.string "encrypted_otp_secret_key" - t.string "encrypted_otp_secret_key_iv" - t.string "encrypted_otp_secret_key_salt" - t.string "direct_otp" - t.datetime "direct_otp_sent_at", precision: nil - t.datetime "totp_timestamp", precision: nil - t.string "phone" - t.string "name" - t.integer "sign_in_count", default: 0, null: false - t.datetime "current_sign_in_at", precision: nil - t.datetime "last_sign_in_at", precision: nil - t.string "current_sign_in_ip" - t.string "last_sign_in_ip" - t.integer "failed_attempts", default: 0 - t.string "unlock_token" - t.datetime "locked_at", precision: nil - t.index ["encrypted_otp_secret_key"], name: "index_admin_users_on_encrypted_otp_secret_key", unique: true - t.index ["unlock_token"], name: "index_admin_users_on_unlock_token", unique: true - end - create_table "case_logs", force: :cascade do |t| t.integer "status", default: 0 t.datetime "created_at", null: false diff --git a/package.json b/package.json index 9086ffff1..ef6f2bd7e 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,6 @@ "node": "^16.0.0" }, "dependencies": { - "@activeadmin/activeadmin": "^2.11.0", "@babel/core": "^7.17.7", "@babel/plugin-transform-runtime": "^7.17.0", "@babel/preset-env": "^7.16.11", diff --git a/spec/controllers/admin/admin_users_controller_spec.rb b/spec/controllers/admin/admin_users_controller_spec.rb deleted file mode 100644 index f1f2ebeab..000000000 --- a/spec/controllers/admin/admin_users_controller_spec.rb +++ /dev/null @@ -1,78 +0,0 @@ -require "rails_helper" -require_relative "../../support/devise" - -describe Admin::AdminUsersController, type: :controller do - render_views - let(:page) { Capybara::Node::Simple.new(response.body) } - let(:resource_title) { "Admin Users" } - let(:valid_session) { {} } - let(:signed_in_admin_user) { FactoryBot.create(:admin_user) } - - before do - sign_in signed_in_admin_user - end - - describe "Get admin users" do - before do - get :index, session: valid_session - end - - it "returns a table of admin users" do - expect(page).to have_content(resource_title) - expect(page).to have_table("index_table_admin_users") - expect(page).to have_link(AdminUser.first.id.to_s) - end - end - - describe "Create admin users" do - let(:params) { { admin_user: { email: "test2@example.com", password: "pAssword1", phone: "07566126368" } } } - - it "creates a new admin user" do - expect { post :create, session: valid_session, params: }.to change(AdminUser, :count).by(1) - end - - it "tracks who created the record" do - post(:create, session: valid_session, params:) - created_id = response.location.match(/[0-9]+/)[0] - whodunnit_actor = AdminUser.find_by(id: created_id).versions.last.actor - expect(whodunnit_actor).to be_a(AdminUser) - expect(whodunnit_actor.id).to eq(signed_in_admin_user.id) - end - end - - describe "Update admin users" do - context "when viewing the form" do - before do - get :edit, session: valid_session, params: { id: AdminUser.first.id } - end - - it "shows the correct fields" do - expect(page).to have_field("admin_user_email") - expect(page).to have_field("admin_user_password") - expect(page).to have_field("admin_user_password_confirmation") - end - end - - context "when updating an admin user" do - let(:admin_user) { FactoryBot.create(:admin_user) } - let(:email) { "new_email@example.com" } - let(:params) { { id: admin_user.id, admin_user: { email: } } } - - before do - patch :update, session: valid_session, params: - end - - it "updates the user without needing to input a password" do - admin_user.reload - expect(admin_user.email).to eq(email) - end - - it "tracks who updated the record" do - admin_user.reload - whodunnit_actor = admin_user.versions.last.actor - expect(whodunnit_actor).to be_a(AdminUser) - expect(whodunnit_actor.id).to eq(signed_in_admin_user.id) - end - end - end -end diff --git a/spec/controllers/admin/case_logs_controller_spec.rb b/spec/controllers/admin/case_logs_controller_spec.rb deleted file mode 100644 index a94e06585..000000000 --- a/spec/controllers/admin/case_logs_controller_spec.rb +++ /dev/null @@ -1,92 +0,0 @@ -require "rails_helper" -require_relative "../../support/devise" - -describe Admin::CaseLogsController, type: :controller do - before do - sign_in admin_user - end - - render_views - let(:page) { Capybara::Node::Simple.new(response.body) } - let(:resource_title) { "Logs" } - let(:valid_session) { {} } - let(:admin_user) { FactoryBot.create(:admin_user) } - let(:user) { FactoryBot.create(:user) } - - describe "Get case logs" do - let!(:case_log) { FactoryBot.create(:case_log, :in_progress) } - - before do - get :index, session: valid_session - end - - it "returns a table of case logs" do - expect(page).to have_content(resource_title) - expect(page).to have_table("index_table_case_logs") - expect(page).to have_link(case_log.id.to_s) - expect(page).to have_link(case_log.owning_organisation.name.to_s) - end - end - - describe "Create case logs" do - let(:owning_organisation) { FactoryBot.create(:organisation) } - let(:managing_organisation) { owning_organisation } - let(:params) do - { - "case_log": { - "owning_organisation_id": owning_organisation.id, - "managing_organisation_id": managing_organisation.id, - "created_by_id": user.id, - }, - } - end - - it "creates a new case log" do - expect { post :create, session: valid_session, params: }.to change(CaseLog, :count).by(1) - end - - it "tracks who created the record" do - post(:create, session: valid_session, params:) - created_id = response.location.match(/[0-9]+/)[0] - whodunnit_actor = CaseLog.find_by(id: created_id).versions.last.actor - expect(whodunnit_actor).to be_a(AdminUser) - expect(whodunnit_actor.id).to eq(admin_user.id) - end - end - - describe "Update case log" do - let!(:case_log) { FactoryBot.create(:case_log, :in_progress) } - - context "when viewing the edit form" do - before do - get :edit, session: valid_session, params: { id: case_log.id } - end - - it "has the correct fields" do - expect(page).to have_field("case_log_age1") - expect(page).to have_field("case_log_tenant_code") - end - end - - context "when updating the case_log" do - let(:tenant_code) { "New tenant code by Admin" } - let(:params) { { id: case_log.id, case_log: { tenant_code: } } } - - before do - patch :update, session: valid_session, params: - end - - it "updates the case log" do - case_log.reload - expect(case_log.tenant_code).to eq(tenant_code) - end - - it "tracks who updated the record" do - case_log.reload - whodunnit_actor = case_log.versions.last.actor - expect(whodunnit_actor).to be_a(AdminUser) - expect(whodunnit_actor.id).to eq(admin_user.id) - end - end - end -end diff --git a/spec/controllers/admin/dashboard_controller_spec.rb b/spec/controllers/admin/dashboard_controller_spec.rb deleted file mode 100644 index 141f53b88..000000000 --- a/spec/controllers/admin/dashboard_controller_spec.rb +++ /dev/null @@ -1,44 +0,0 @@ -require "rails_helper" -require_relative "../../support/devise" - -describe Admin::DashboardController, type: :controller do - before do - sign_in admin_user - end - - render_views - let(:page) { Capybara::Node::Simple.new(response.body) } - let(:resource_title) { "Dashboard" } - let(:valid_session) { {} } - let(:admin_user) { FactoryBot.create(:admin_user) } - - describe "Get case logs" do - before do - 2.times { |_| FactoryBot.create(:case_log, :in_progress) } - FactoryBot.create(:case_log, :completed) - get :index, session: valid_session - end - - it "returns a dashboard page" do - expect(page).to have_content(resource_title) - end - - it "returns a panel of recent case logs" do - expect(page).to have_xpath("//div[contains(@class, 'panel') and contains(//h3, 'Recent logs')]") - end - - it "returns a panel of in progress case logs" do - panel_xpath = "//div[@class='panel' and .//h3[contains(., 'Total logs in progress')]]" - panel_content_xpath = "#{panel_xpath}//div[@class='panel_contents' and .//p[contains(., 2)]]" - expect(page).to have_xpath(panel_xpath) - expect(page).to have_xpath(panel_content_xpath) - end - - it "returns a panel of completed case logs" do - panel_xpath = "//div[@class='panel' and .//h3[contains(., 'Total logs completed')]]" - panel_content_xpath = "#{panel_xpath}//div[@class='panel_contents' and .//p[contains(., 1)]]" - expect(page).to have_xpath(panel_xpath) - expect(page).to have_xpath(panel_content_xpath) - end - end -end diff --git a/spec/controllers/admin/organisations_controller_spec.rb b/spec/controllers/admin/organisations_controller_spec.rb deleted file mode 100644 index d66bc3c4c..000000000 --- a/spec/controllers/admin/organisations_controller_spec.rb +++ /dev/null @@ -1,78 +0,0 @@ -require "rails_helper" -require_relative "../../support/devise" - -describe Admin::OrganisationsController, type: :controller do - render_views - let(:page) { Capybara::Node::Simple.new(response.body) } - let(:resource_title) { "Organisations" } - let(:valid_session) { {} } - let!(:organisation) { FactoryBot.create(:organisation) } - let!(:admin_user) { FactoryBot.create(:admin_user) } - - before do - sign_in admin_user - end - - describe "Organisations" do - before do - get :index, session: valid_session - end - - it "returns a table of admin users" do - expect(page).to have_content(resource_title) - expect(page).to have_table("index_table_organisations") - expect(page).to have_link(organisation.id.to_s) - end - end - - describe "Create organisation" do - let(:params) { { organisation: { name: "DLUHC", provider_type: "LA" } } } - - it "creates a organisation" do - expect { post :create, session: valid_session, params: }.to change(Organisation, :count).by(1) - end - - it "tracks who created the record" do - post(:create, session: valid_session, params:) - created_id = response.location.match(/[0-9]+/)[0] - whodunnit_actor = Organisation.find_by(id: created_id).versions.last.actor - expect(whodunnit_actor).to be_a(AdminUser) - expect(whodunnit_actor.id).to eq(admin_user.id) - end - end - - describe "Update organisation" do - context "when viewing the edit form" do - before do - get :edit, session: valid_session, params: { id: organisation.id } - end - - it "has the correct fields" do - expect(page).to have_field("organisation_name") - expect(page).to have_field("organisation_provider_type") - expect(page).to have_field("organisation_phone") - end - end - - context "when updating the organisation" do - let(:name) { "New Org Name by Admin" } - let(:params) { { id: organisation.id, organisation: { name: } } } - - before do - patch :update, session: valid_session, params: - end - - it "updates the organisation" do - organisation.reload - expect(organisation.name).to eq(name) - end - - it "tracks who updated the record" do - organisation.reload - whodunnit_actor = organisation.versions.last.actor - expect(whodunnit_actor).to be_a(AdminUser) - expect(whodunnit_actor.id).to eq(admin_user.id) - end - end - end -end diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb deleted file mode 100644 index 4ed4ab8ed..000000000 --- a/spec/controllers/admin/users_controller_spec.rb +++ /dev/null @@ -1,97 +0,0 @@ -require "rails_helper" -require_relative "../../support/devise" - -describe Admin::UsersController, type: :controller do - render_views - let!(:user) { FactoryBot.create(:user) } - let(:organisation) { FactoryBot.create(:organisation) } - let(:page) { Capybara::Node::Simple.new(response.body) } - let(:resource_title) { "Users" } - let(:valid_session) { {} } - let!(:admin_user) { FactoryBot.create(:admin_user) } - let(:notify_client) { instance_double(Notifications::Client) } - let(:devise_notify_mailer) { DeviseNotifyMailer.new } - - before do - allow(DeviseNotifyMailer).to receive(:new).and_return(devise_notify_mailer) - allow(devise_notify_mailer).to receive(:notify_client).and_return(notify_client) - allow(notify_client).to receive(:send_email).and_return(true) - sign_in admin_user - end - - describe "Get users" do - before do - get :index, session: valid_session - end - - it "returns a table of users" do - expect(page).to have_content(resource_title) - expect(page).to have_table("index_table_users") - expect(page).to have_link(user.id.to_s) - end - end - - describe "Create users" do - let(:params) do - { - user: { - email: "somethin5@example.com", - name: "Jane", - password: "pAssword1", - organisation_id: organisation.id, - role: "data_coordinator", - }, - } - end - - it "creates a new user" do - expect { post :create, session: valid_session, params: }.to change(User, :count).by(1) - end - - it "tracks who created the record" do - post(:create, session: valid_session, params:) - created_id = response.location.match(/[0-9]+/)[0] - whodunnit_actor = User.find_by(id: created_id).versions.last.actor - expect(whodunnit_actor).to be_a(AdminUser) - expect(whodunnit_actor.id).to eq(admin_user.id) - end - end - - describe "Update users" do - context "when viewing the edit form" do - before do - get :edit, session: valid_session, params: { id: user.id } - end - - it "has the correct fields" do - expect(page).to have_field("user_email") - expect(page).to have_field("user_name") - expect(page).to have_field("user_organisation_id") - expect(page).to have_field("user_role") - expect(page).to have_field("user_password") - expect(page).to have_field("user_password_confirmation") - end - end - - context "when updating the user" do - let(:name) { "Pete" } - let(:params) { { id: user.id, user: { name: } } } - - before do - patch :update, session: valid_session, params: - end - - it "updates the user without needing to input a password" do - user.reload - expect(user.name).to eq(name) - end - - it "tracks who updated the record" do - user.reload - whodunnit_actor = user.versions.last.actor - expect(whodunnit_actor).to be_a(AdminUser) - expect(whodunnit_actor.id).to eq(admin_user.id) - end - end - end -end diff --git a/spec/features/admin_panel_spec.rb b/spec/features/admin_panel_spec.rb deleted file mode 100644 index 7c721deac..000000000 --- a/spec/features/admin_panel_spec.rb +++ /dev/null @@ -1,162 +0,0 @@ -require "rails_helper" - -RSpec.describe "Admin Panel" do - let!(:admin) { FactoryBot.create(:admin_user) } - let(:devise_notify_mailer) { DeviseNotifyMailer.new } - let(:notify_client) { instance_double(Notifications::Client) } - let(:mfa_template_id) { AdminUser::MFA_TEMPLATE_ID } - let(:otp) { "999111" } - - before do - allow(DeviseNotifyMailer).to receive(:new).and_return(devise_notify_mailer) - allow(devise_notify_mailer).to receive(:notify_client).and_return(notify_client) - allow(notify_client).to receive(:send_email).and_return(true) - end - - it "shows the admin sign in page" do - visit("/admin") - expect(page).to have_current_path("/admin/sign-in") - expect(page).to have_content("Sign in to your CORE administration account") - end - - context "with a valid 2FA code" do - before do - allow(SecureRandom).to receive(:random_number).and_return(otp) - visit("/admin") - fill_in("admin_user[email]", with: admin.email) - fill_in("admin_user[password]", with: admin.password) - end - - it "authenticates successfully" do - expect(notify_client).to receive(:send_email).with( - { - email_address: admin.email, - template_id: mfa_template_id, - personalisation: { otp: }, - }, - ) - click_button("Sign in") - fill_in("code", with: otp) - click_button("Submit") - expect(page).to have_content("Dashboard") - expect(page).to have_content(I18n.t("devise.two_factor_authentication.success")) - end - - context "but it is more than 15 minutes old" do - it "does not authenticate successfully" do - click_button("Sign in") - admin.update!(direct_otp_sent_at: 16.minutes.ago) - fill_in("code", with: otp) - click_button("Submit") - expect(page).to have_content("Check your email") - expect(page).to have_http_status(:unprocessable_entity) - expect(page).to have_title("Error") - expect(page).to have_selector("#error-summary-title") - end - end - end - - context "with an invalid 2FA code" do - it "does not authenticate successfully" do - visit("/admin") - fill_in("admin_user[email]", with: admin.email) - fill_in("admin_user[password]", with: admin.password) - click_button("Sign in") - fill_in("code", with: otp) - click_button("Submit") - expect(page).to have_content("Check your email") - expect(page).to have_http_status(:unprocessable_entity) - expect(page).to have_title("Error") - expect(page).to have_selector("#error-summary-title") - end - end - - context "when the 2FA code needs to be resent" do - before do - visit("/admin") - fill_in("admin_user[email]", with: admin.email) - fill_in("admin_user[password]", with: admin.password) - click_button("Sign in") - end - - it "displays the resend view" do - click_link("Not received an email?") - expect(page).to have_button("Resend security code") - end - - it "send a new OTP code and redirects back to the 2FA view" do - click_link("Not received an email?") - expect { click_button("Resend security code") }.to(change { admin.reload.direct_otp }) - expect(page).to have_current_path("/admin/two-factor-authentication") - end - end - - context "when logging out and in again" do - before do - allow(SecureRandom).to receive(:random_number).and_return(otp) - end - - it "requires the 2FA code on each login" do - visit("/admin") - fill_in("admin_user[email]", with: admin.email) - fill_in("admin_user[password]", with: admin.password) - click_button("Sign in") - fill_in("code", with: otp) - click_button("Submit") - click_link("Logout") - visit("/admin") - fill_in("admin_user[email]", with: admin.email) - fill_in("admin_user[password]", with: admin.password) - click_button("Sign in") - expect(page).to have_content("Check your email") - end - end - - context "when the admin has forgotten their password" do - let!(:admin_user) { FactoryBot.create(:admin_user, last_sign_in_at: Time.zone.now) } - let(:reset_password_token) { "MCDH5y6Km-U7CFPgAMVS" } - - before do - allow(Devise.token_generator).to receive(:generate).and_return(reset_password_token) - end - - it " is redirected to the reset password page when they click the reset password link" do - visit("/admin") - click_link("reset your password") - expect(page).to have_current_path("/admin/password/new") - end - - it " is shown an error message if they submit without entering an email address" do - visit("/admin/password/new") - click_button("Send email") - expect(page).to have_selector("#error-summary-title") - expect(page).to have_selector("#user-email-field-error") - expect(page).to have_title("Error") - end - - it " is redirected to admin login page after reset email is sent" do - visit("/admin/password/new") - fill_in("admin_user[email]", with: admin_user.email) - click_button("Send email") - expect(page).to have_content("Check your email") - end - - it " is sent a reset password email via Notify" do - expect(notify_client).to receive(:send_email).with( - { - email_address: admin_user.email, - template_id: admin_user.reset_password_notify_template, - personalisation: { - name: admin_user.email, - email: admin_user.email, - organisation: "", - link: "http://localhost:3000/admin/password/edit?reset_password_token=#{reset_password_token}", - }, - }, - ) - visit("/admin/password/new") - fill_in("admin_user[email]", with: admin_user.email) - click_button("Send email") - end - end -end diff --git a/spec/features/auth/user_lockout_spec.rb b/spec/features/auth/user_lockout_spec.rb index c1ba131df..68cf78b2a 100644 --- a/spec/features/auth/user_lockout_spec.rb +++ b/spec/features/auth/user_lockout_spec.rb @@ -2,7 +2,6 @@ require "rails_helper" RSpec.describe "User Lockout" do let(:user) { FactoryBot.create(:user) } - let(:admin) { FactoryBot.create(:admin_user) } let(:max_login_attempts) { Devise.maximum_attempts } let(:max_2fa_attempts) { Devise.max_login_attempts } let(:notify_client) { instance_double(Notifications::Client) } @@ -26,53 +25,4 @@ RSpec.describe "User Lockout" do expect(page).to have_content(I18n.t("devise.failure.locked")) end end - - context "when login-in with the wrong admin password up to a maximum number of attempts" do - before do - visit("/admin/sign-in") - max_login_attempts.times do - fill_in("admin_user[email]", with: admin.email) - fill_in("admin_user[password]", with: "wrong_password") - click_button("Sign in") - end - end - - it "locks the admin account" do - visit("/admin/sign-in") - fill_in("admin_user[email]", with: admin.email) - fill_in("admin_user[password]", with: admin.password) - click_button("Sign in") - expect(page).to have_http_status(:unprocessable_entity) - expect(page).to have_content(I18n.t("devise.failure.locked")) - end - end - - context "when login-in with the right admin password and incorrect 2FA token up to a maximum number of attempts" do - let(:devise_notify_mailer) { DeviseNotifyMailer.new } - - before do - allow(DeviseNotifyMailer).to receive(:new).and_return(devise_notify_mailer) - allow(devise_notify_mailer).to receive(:notify_client).and_return(notify_client) - allow(notify_client).to receive(:send_email).and_return(true) - - visit("/admin/sign-in") - fill_in("admin_user[email]", with: admin.email) - fill_in("admin_user[password]", with: admin.password) - click_button("Sign in") - - max_2fa_attempts.times do - fill_in("code", with: "random") - click_button("Submit") - end - end - - it "locks the admin account" do - visit("/admin/sign-in") - fill_in("admin_user[email]", with: admin.email) - fill_in("admin_user[password]", with: admin.password) - click_button("Sign in") - expect(page).to have_http_status(:unprocessable_entity) - expect(page).to have_content(I18n.t("devise.two_factor_authentication.account_locked")) - end - end end diff --git a/spec/models/admin_user_spec.rb b/spec/models/admin_user_spec.rb deleted file mode 100644 index 5510325d1..000000000 --- a/spec/models/admin_user_spec.rb +++ /dev/null @@ -1,84 +0,0 @@ -require "rails_helper" - -RSpec.describe AdminUser, type: :model do - describe "#new" do - it "requires a phone number" do - expect { - described_class.create!( - email: "admin_test@example.com", - password: "password123", - ) - }.to raise_error(ActiveRecord::RecordInvalid) - end - - it "requires a numerical phone number" do - expect { - described_class.create!( - email: "admin_test@example.com", - password: "password123", - phone: "string", - ) - }.to raise_error(ActiveRecord::RecordInvalid) - end - - it "requires an email" do - expect { - described_class.create!( - password: "password123", - phone: "075752137", - ) - }.to raise_error(ActiveRecord::RecordInvalid) - end - - it "requires a password" do - expect { - described_class.create!( - email: "admin_test@example.com", - phone: "075752137", - ) - }.to raise_error(ActiveRecord::RecordInvalid) - end - - it "can be created" do - expect { - described_class.create!( - email: "admin_test@example.com", - password: "password123", - phone: "075752137", - ) - }.to change(described_class, :count).by(1) - end - end - - describe "paper trail" do - let(:admin_user) { FactoryBot.create(:admin_user) } - - it "creates a record of changes to a log" do - expect { admin_user.update!(phone: "09673867853") }.to change(admin_user.versions, :count).by(1) - end - - it "allows case logs to be restored to a previous version" do - admin_user.update!(phone: "09673867853") - expect(admin_user.paper_trail.previous_version.phone).to eq("07563867654") - end - - it "signing in does not create a new version" do - expect { - admin_user.update!( - last_sign_in_at: Time.zone.now, - current_sign_in_at: Time.zone.now, - current_sign_in_ip: "127.0.0.1", - last_sign_in_ip: "127.0.0.1", - failed_attempts: 3, - unlock_token: "dummy", - locked_at: Time.zone.now, - reset_password_token: "dummy", - reset_password_sent_at: Time.zone.now, - remember_created_at: Time.zone.now, - sign_in_count: 5, - updated_at: Time.zone.now, - ) - }.not_to change(admin_user.versions, :count) - end - end -end diff --git a/spec/requests/auth/passwords_controller_spec.rb b/spec/requests/auth/passwords_controller_spec.rb index 0615e8257..888bb8c70 100644 --- a/spec/requests/auth/passwords_controller_spec.rb +++ b/spec/requests/auth/passwords_controller_spec.rb @@ -73,78 +73,6 @@ RSpec.describe Auth::PasswordsController, type: :request do end end - context "when an admin user" do - let(:admin_user) { FactoryBot.create(:admin_user) } - - describe "reset password" do - let(:new_value) { "new-password" } - - before do - allow(DeviseNotifyMailer).to receive(:notify_client).and_return(notify_client) - allow(notify_client).to receive(:send_email).and_return(true) - end - - it "renders the user edit password view" do - _raw, enc = Devise.token_generator.generate(AdminUser, :reset_password_token) - get "/admin/password/edit?reset_password_token=#{enc}" - expect(page).to have_css("h1", text: I18n.t("user.reset_password")) - end - - context "when passwords entered don't match" do - let(:raw) { admin_user.send_reset_password_instructions } - let(:params) do - { - id: admin_user.id, - admin_user: { - password: new_value, - password_confirmation: "something_else", - reset_password_token: raw, - }, - } - end - - it "shows an error" do - put "/admin/password", headers: headers, params: params - expect(response).to have_http_status(:unprocessable_entity) - expect(page).to have_content("doesn’t match new password") - end - end - - context "when passwords is reset" do - let(:raw) { admin_user.send_reset_password_instructions } - let(:params) do - { - id: admin_user.id, - admin_user: { - password: new_value, - password_confirmation: new_value, - reset_password_token: raw, - }, - } - end - - it "updates the password" do - expect { - put "/admin/password", headers: headers, params: params - admin_user.reload - }.to change(admin_user, :encrypted_password) - end - - it "sends you to the 2FA page and does not allow bypassing 2FA code" do - put "/admin/password", headers: headers, params: params - expect(response).to redirect_to("/admin/two-factor-authentication") - get "/admin/case_logs", headers: headers - expect(response).to redirect_to("/admin/two-factor-authentication") - end - - it "triggers an email" do - expect(notify_client).to receive(:send_email) - put "/admin/password", headers:, params: - end - end - end - end - context "when a customer support user" do let(:support_user) { FactoryBot.create(:user, :support) } diff --git a/spec/requests/rack_attack_spec.rb b/spec/requests/rack_attack_spec.rb index a7d4bd34c..25ad55cac 100644 --- a/spec/requests/rack_attack_spec.rb +++ b/spec/requests/rack_attack_spec.rb @@ -12,11 +12,8 @@ describe "Rack::Attack" do let(:devise_notify_mailer) { DeviseNotifyMailer.new } let(:params) { { user: { email: } } } - let(:admin_params) { { admin_user: { email: admin_email } } } let(:user) { FactoryBot.create(:user) } - let(:admin_user) { FactoryBot.create(:admin_user) } let(:email) { user.email } - let(:admin_email) { admin_user.email } before do Rack::Attack.enabled = true @@ -40,15 +37,6 @@ describe "Rack::Attack" do last_response = response expect(last_response.status).to eq(200) end - - it "does not throttle for an admin user" do - under_limit.times do - post "/admin/password", params: admin_params - follow_redirect! - end - last_response = response - expect(last_response.status).to eq(200) - end end context "when the number of requests is at the throttle limit" do @@ -60,26 +48,6 @@ describe "Rack::Attack" do last_response = response expect(last_response.status).to eq(200) end - - it "does not throttle for an admin user" do - limit.times do - post "/admin/password", params: admin_params - follow_redirect! - end - last_response = response - expect(last_response.status).to eq(200) - end - - it "does not throttle if both endpoints are hit" do - limit.times do - post "/account/password", params: params - follow_redirect! - post "/admin/password", params: admin_params - follow_redirect! - end - last_response = response - expect(last_response.status).to eq(200) - end end context "when the number of requests is over the throttle limit" do @@ -91,15 +59,6 @@ describe "Rack::Attack" do last_response = response expect(last_response.status).to eq(429) end - - it "throttles for an admin user" do - over_limit.times do - post "/admin/password", params: admin_params - follow_redirect! - end - last_response = response - expect(last_response.status).to eq(429) - end end end end diff --git a/webpack.config.js b/webpack.config.js index 77eebab44..c22a0a141 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -13,10 +13,6 @@ module.exports = { entry: { application: [ "./app/frontend/application.js", - ], - active_admin: [ - './app/frontend/active_admin.js', - './app/frontend/styles/active_admin.scss' ] }, module: { @@ -68,12 +64,6 @@ module.exports = { { from: "app/frontend/vendor/outerHTML.js", to: "vendor" }, { from: "app/frontend/vendor/polyfill-output-value.js", to: "vendor" } ], - }), - new webpack.ProvidePlugin({ - $: 'jquery', - jQuery: 'jquery', - jquery: 'jquery', - 'window.jQuery': 'jquery' }) ] } diff --git a/yarn.lock b/yarn.lock index 3734c0edd..62de9ae2b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,15 +2,6 @@ # yarn lockfile v1 -"@activeadmin/activeadmin@^2.11.0": - version "2.12.0" - resolved "https://registry.yarnpkg.com/@activeadmin/activeadmin/-/activeadmin-2.12.0.tgz#f0f69fbc5828a538802512884304744e3d94a619" - integrity sha512-2paDrb1ZGy9T1W+LETV0nje/LmCqhqDZSEXtOKvRiC9zGMVh6IwjUD82C1ISfi5jg3VIrMihQ9tECIAS9d1f9w== - dependencies: - jquery "^3.4.1" - jquery-ui "^1.12.1" - jquery-ujs "^1.2.2" - "@ampproject/remapping@^2.1.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" @@ -2249,23 +2240,6 @@ jest-worker@^27.4.5: merge-stream "^2.0.0" supports-color "^8.0.0" -jquery-ui@^1.12.1: - version "1.13.1" - resolved "https://registry.yarnpkg.com/jquery-ui/-/jquery-ui-1.13.1.tgz#d0b7a42e73a04c31bb5706adf86f6f8942f64eaa" - integrity sha512-2VlU59N5P4HaumDK1Z3XEVjSvegFbEOQRgpHUBaB2Ak98Axl3hFhJ6RFcNQNuk9SfL6WxIbuLst8dW/U56NSiA== - dependencies: - jquery ">=1.8.0 <4.0.0" - -jquery-ujs@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/jquery-ujs/-/jquery-ujs-1.2.3.tgz#dcac6026ab7268e5ee41faf9d31c997cd4ddd603" - integrity sha512-59wvfx5vcCTHMeQT1/OwFiAj+UffLIwjRIoXdpO7Z7BCFGepzq9T9oLVeoItjTqjoXfUrHJvV7QU6pUR+UzOoA== - -"jquery@>=1.8.0 <4.0.0", jquery@^3.4.1: - version "3.6.0" - resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.6.0.tgz#c72a09f15c1bdce142f49dbf1170bdf8adac2470" - integrity sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw== - js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"