From a5911f5c6aecb2f3bf857e0371731b2ab1f3ce3c Mon Sep 17 00:00:00 2001 From: taitus Date: Fri, 23 Dec 2022 12:13:35 +0100 Subject: [PATCH] Modify admin layout to only manage tenants and admins We only want to render the account link and login items in the header. And we want only render the Multitenancy and Administrators sections in the admin sidebar. We include the administrators management so it's possible to give permissions to other users to manage tenants. In order to restrict access to other sections by typing the URL or following a link, we're only enabling the rest of the routes when we aren't in the multitenancy management mode. --- app/assets/stylesheets/admin/menu.scss | 8 + app/components/admin/menu_component.rb | 54 +- .../layout/admin_header_component.html.erb | 6 +- .../layout/admin_header_component.rb | 4 + .../layout/admin_login_items_component.rb | 2 +- app/components/layout/footer_component.rb | 4 + .../layout/login_items_component.html.erb | 18 +- .../layout/login_items_component.rb | 6 + .../layout/notification_item_component.rb | 2 +- .../layout/subnavigation_component.rb | 4 + app/controllers/users/sessions_controller.rb | 4 +- config/application.rb | 4 + config/routes.rb | 73 +-- config/routes/admin.rb | 585 +++++++++--------- config/routes/custom.rb | 9 + spec/components/admin/menu_component_spec.rb | 13 +- .../layout/admin_header_component_spec.rb | 9 + .../admin_login_items_component_spec.rb | 9 + .../layout/footer_component_spec.rb | 7 + .../layout/login_items_component_spec.rb | 11 + .../notification_item_component_spec.rb | 7 + .../layout/subnavigation_component_spec.rb | 10 + .../users/sessions_controller_spec.rb | 18 + .../multitenancy_management_mode_spec.rb | 28 + 24 files changed, 535 insertions(+), 360 deletions(-) create mode 100644 spec/components/layout/login_items_component_spec.rb create mode 100644 spec/components/layout/subnavigation_component_spec.rb create mode 100644 spec/system/multitenancy_management_mode_spec.rb diff --git a/app/assets/stylesheets/admin/menu.scss b/app/assets/stylesheets/admin/menu.scss index 4228ea197..ce2c0f41c 100644 --- a/app/assets/stylesheets/admin/menu.scss +++ b/app/assets/stylesheets/admin/menu.scss @@ -109,6 +109,14 @@ &.ml-link { @include icon(brain, solid); } + + &.administrators-link { + @include icon(user, solid); + } + + &.tenants-link { + @include icon(building, regular); + } } li { diff --git a/app/components/admin/menu_component.rb b/app/components/admin/menu_component.rb index dba560278..d25e0860f 100644 --- a/app/components/admin/menu_component.rb +++ b/app/components/admin/menu_component.rb @@ -3,28 +3,40 @@ class Admin::MenuComponent < ApplicationComponent use_helpers :can? def links - [ - (proposals_link if feature?(:proposals)), - (debates_link if feature?(:debates)), - comments_link, - (polls_link if feature?(:polls)), - (legislation_link if feature?(:legislation)), - (budgets_link if feature?(:budgets)), - booths_links, - (signature_sheets_link if feature?(:signature_sheets)), - messages_links, - site_customization_links, - moderated_content_links, - profiles_links, - stats_link, - settings_links, - dashboard_links, - (machine_learning_link if ::MachineLearning.enabled?) - ] + if Rails.application.multitenancy_management_mode? + multitenancy_management_links + else + default_links + end end private + def default_links + [ + (proposals_link if feature?(:proposals)), + (debates_link if feature?(:debates)), + comments_link, + (polls_link if feature?(:polls)), + (legislation_link if feature?(:legislation)), + (budgets_link if feature?(:budgets)), + booths_links, + (signature_sheets_link if feature?(:signature_sheets)), + messages_links, + site_customization_links, + moderated_content_links, + profiles_links, + stats_link, + settings_links, + dashboard_links, + (machine_learning_link if ::MachineLearning.enabled?) + ] + end + + def multitenancy_management_links + [tenants_link, administrators_link] + end + def moderated_content? moderated_sections.include?(controller_name) && controller.class.module_parent != Admin::Legislation end @@ -395,7 +407,8 @@ class Admin::MenuComponent < ApplicationComponent [ t("admin.menu.administrators"), admin_administrators_path, - controller_name == "administrators" + controller_name == "administrators", + class: "administrators-link" ] end @@ -482,7 +495,8 @@ class Admin::MenuComponent < ApplicationComponent [ t("admin.menu.multitenancy"), admin_tenants_path, - controller_name == "tenants" + controller_name == "tenants", + class: "tenants-link" ] end end diff --git a/app/components/layout/admin_header_component.html.erb b/app/components/layout/admin_header_component.html.erb index 9975ed46d..99d48e18a 100644 --- a/app/components/layout/admin_header_component.html.erb +++ b/app/components/layout/admin_header_component.html.erb @@ -2,8 +2,10 @@ diff --git a/app/components/layout/admin_header_component.rb b/app/components/layout/admin_header_component.rb index f28690c53..0320e84e8 100644 --- a/app/components/layout/admin_header_component.rb +++ b/app/components/layout/admin_header_component.rb @@ -29,4 +29,8 @@ class Layout::AdminHeaderComponent < ApplicationComponent def show_account_menu? show_admin_menu?(user) || namespace != "management" end + + def show_link_to_root_path? + !Rails.application.multitenancy_management_mode? + end end diff --git a/app/components/layout/admin_login_items_component.rb b/app/components/layout/admin_login_items_component.rb index 91f0fd7db..e19ad433d 100644 --- a/app/components/layout/admin_login_items_component.rb +++ b/app/components/layout/admin_login_items_component.rb @@ -7,7 +7,7 @@ class Layout::AdminLoginItemsComponent < ApplicationComponent end def render? - show_admin_menu?(user) + show_admin_menu?(user) && !Rails.application.multitenancy_management_mode? end private diff --git a/app/components/layout/footer_component.rb b/app/components/layout/footer_component.rb index 555dde0d8..49d6d59f2 100644 --- a/app/components/layout/footer_component.rb +++ b/app/components/layout/footer_component.rb @@ -1,6 +1,10 @@ class Layout::FooterComponent < ApplicationComponent use_helpers :content_block + def render? + !Rails.application.multitenancy_management_mode? + end + def footer_legal_content_block content_block("footer_legal") end diff --git a/app/components/layout/login_items_component.html.erb b/app/components/layout/login_items_component.html.erb index 048ef300d..73220dffb 100644 --- a/app/components/layout/login_items_component.html.erb +++ b/app/components/layout/login_items_component.html.erb @@ -1,12 +1,14 @@ <% if user %> -
  • - <%= layout_menu_link_to t("layouts.header.my_activity_link"), - user_path(user), - controller_name == "users", - rel: "nofollow", - title: t("shared.go_to_page") + - t("layouts.header.my_activity_link") %> -
  • + <% if show_my_activity_link? %> +
  • + <%= layout_menu_link_to t("layouts.header.my_activity_link"), + user_path(user), + controller_name == "users", + rel: "nofollow", + title: t("shared.go_to_page") + + t("layouts.header.my_activity_link") %> +
  • + <% end %>
  • <%= layout_menu_link_to t("layouts.header.my_account_link"), account_path, diff --git a/app/components/layout/login_items_component.rb b/app/components/layout/login_items_component.rb index 8c1e79bce..adbe892c7 100644 --- a/app/components/layout/login_items_component.rb +++ b/app/components/layout/login_items_component.rb @@ -5,4 +5,10 @@ class Layout::LoginItemsComponent < ApplicationComponent def initialize(user) @user = user end + + private + + def show_my_activity_link? + !Rails.application.multitenancy_management_mode? + end end diff --git a/app/components/layout/notification_item_component.rb b/app/components/layout/notification_item_component.rb index 5a767e418..6b30f4ab4 100644 --- a/app/components/layout/notification_item_component.rb +++ b/app/components/layout/notification_item_component.rb @@ -6,7 +6,7 @@ class Layout::NotificationItemComponent < ApplicationComponent end def render? - user.present? + user.present? && !Rails.application.multitenancy_management_mode? end private diff --git a/app/components/layout/subnavigation_component.rb b/app/components/layout/subnavigation_component.rb index 6da3b320b..5fdaa0c49 100644 --- a/app/components/layout/subnavigation_component.rb +++ b/app/components/layout/subnavigation_component.rb @@ -1,3 +1,7 @@ class Layout::SubnavigationComponent < ApplicationComponent use_helpers :content_block, :layout_menu_link_to + + def render? + !Rails.application.multitenancy_management_mode? + end end diff --git a/app/controllers/users/sessions_controller.rb b/app/controllers/users/sessions_controller.rb index 338f3ee0d..98306b99f 100644 --- a/app/controllers/users/sessions_controller.rb +++ b/app/controllers/users/sessions_controller.rb @@ -7,7 +7,9 @@ class Users::SessionsController < Devise::SessionsController private def after_sign_in_path_for(resource) - if !verifying_via_email? && resource.show_welcome_screen? + if Rails.application.multitenancy_management_mode? && !resource.administrator? + account_path + elsif !verifying_via_email? && resource.show_welcome_screen? welcome_path else super diff --git a/config/application.rb b/config/application.rb index 0f75f019c..593c41866 100644 --- a/config/application.rb +++ b/config/application.rb @@ -161,6 +161,10 @@ module Consul config.multitenancy = Rails.application.secrets.multitenancy # Set to true if you want that the default tenant only to be used to manage other tenants config.multitenancy_management_mode = Rails.application.secrets.multitenancy_management_mode + + def multitenancy_management_mode? + config.multitenancy && Tenant.default? && config.multitenancy_management_mode + end end end diff --git a/config/routes.rb b/config/routes.rb index bdf6af8a6..becc72b7d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -6,46 +6,49 @@ Rails.application.routes.draw do draw :account draw :admin - draw :budget - draw :comment - draw :community - draw :debate draw :devise - draw :direct_upload - draw :document - draw :graphql - draw :legislation - draw :management - draw :moderation - draw :notification - draw :officing - draw :poll - draw :proposal - draw :related_content - draw :sdg - draw :sdg_management - draw :tag - draw :user - draw :valuation - draw :verification - root "welcome#index" - get "/welcome", to: "welcome#welcome" - get "/consul.json", to: "installation#details" - get "robots.txt", to: "robots#index" + constraints lambda { |request| !Rails.application.multitenancy_management_mode? } do + draw :budget + draw :comment + draw :community + draw :debate + draw :direct_upload + draw :document + draw :graphql + draw :legislation + draw :management + draw :moderation + draw :notification + draw :officing + draw :poll + draw :proposal + draw :related_content + draw :sdg + draw :sdg_management + draw :tag + draw :user + draw :valuation + draw :verification - resources :images, only: [:destroy] - resources :documents, only: [:destroy] - resources :follows, only: [:create, :destroy] - resources :remote_translations, only: [:create] + root "welcome#index" + get "/welcome", to: "welcome#welcome" + get "/consul.json", to: "installation#details" + get "robots.txt", to: "robots#index" - # More info pages - get "help", to: "pages#show", id: "help/index", as: "help" - get "help/how-to-use", to: "pages#show", id: "help/how_to_use/index", as: "how_to_use" - get "help/faq", to: "pages#show", id: "faq", as: "faq" + resources :images, only: [:destroy] + resources :documents, only: [:destroy] + resources :follows, only: [:create, :destroy] + resources :remote_translations, only: [:create] - # Static pages - resources :pages, path: "/", only: [:show] + # More info pages + get "help", to: "pages#show", id: "help/index", as: "help" + get "help/how-to-use", to: "pages#show", id: "help/how_to_use/index", as: "how_to_use" + get "help/faq", to: "pages#show", id: "faq", as: "faq" + + # Static pages + resources :pages, path: "/", only: [:show] + end resolve "Budget::Investment" do |investment, options| [investment.budget, :investment, options.merge(id: investment)] diff --git a/config/routes/admin.rb b/config/routes/admin.rb index 9709300d3..ed300820a 100644 --- a/config/routes/admin.rb +++ b/config/routes/admin.rb @@ -1,307 +1,310 @@ namespace :admin do root to: "dashboard#index" - resources :organizations, only: :index do - get :search, on: :collection - member do - put :verify - put :reject - end - end - - resources :hidden_users, only: [:index, :show] do - member do - put :restore - put :confirm_hide - end - end - - resources :hidden_budget_investments, only: :index do - member do - put :restore - put :confirm_hide - end - end - - resources :hidden_debates, only: :index do - member do - put :restore - put :confirm_hide - end - end - - resources :debates, only: [:index, :show] - - resources :proposals, only: [:index, :show, :update] do - member do - patch :select - patch :deselect - end - - resources :milestones, controller: "proposal_milestones" - resources :progress_bars, except: :show, controller: "proposal_progress_bars" - end - - resources :hidden_proposals, only: :index do - member do - put :restore - put :confirm_hide - end - end - - resources :hidden_proposal_notifications, only: :index do - member do - put :restore - put :confirm_hide - end - end - - resources :budgets, except: [:create, :new] do - member do - patch :publish - put :calculate_winners - end - - resources :groups, except: [:index, :show], controller: "budget_groups" do - resources :headings, except: [:index, :show], controller: "budget_headings" - end - - resources :budget_investments, only: [:index, :show, :edit, :update] do - member do - patch :select - patch :deselect - patch :show_to_valuators - patch :hide_from_valuators - end - - resources :audits, only: :show, controller: "budget_investment_audits" - resources :milestones, controller: "budget_investment_milestones" - resources :progress_bars, except: :show, controller: "budget_investment_progress_bars" - end - - resources :budget_phases, only: [:edit, :update] do - member do - patch :enable - patch :disable - end - end - end - - namespace :budgets_wizard do - resources :budgets, only: [:create, :new, :edit, :update] do - resources :groups, only: [:index, :create, :edit, :update, :destroy] do - resources :headings, only: [:index, :create, :edit, :update, :destroy] - end - - resources :phases, as: "budget_phases", only: [:index, :edit, :update] do - member do - patch :enable - patch :disable - end - end - end - end - - resources :milestone_statuses, only: [:index, :new, :create, :update, :edit, :destroy] - - resources :signature_sheets, only: [:index, :new, :create, :show] - - resources :banners, only: [:index, :new, :create, :edit, :update, :destroy] do - collection { get :search } - end - - resources :hidden_comments, only: :index do - member do - put :restore - put :confirm_hide - end - end - - resources :comments, only: :index - - resources :tags, only: [:index, :create, :update, :destroy] - - resources :officials, only: [:index, :edit, :update, :destroy] do - get :search, on: :collection - end - - resources :settings, only: [:index, :update] - put :update_map, to: "settings#update_map" - put :update_content_types, to: "settings#update_content_types" - - resources :moderators, only: [:index, :create, :destroy] do - get :search, on: :collection - end - - resources :valuators, only: [:show, :index, :edit, :update, :create, :destroy] do - get :search, on: :collection - get :summary, on: :collection - end - - resources :valuator_groups - - resources :managers, only: [:index, :create, :destroy] do - get :search, on: :collection - end - - namespace :sdg do - resources :managers, only: [:index, :create, :destroy] - end resources :administrators, only: [:index, :create, :destroy, :edit, :update] do get :search, on: :collection end - resources :users, only: [:index, :show] - - scope module: :poll do - resources :polls do - get :booth_assignments, on: :collection - - resources :booth_assignments, only: [:index, :show, :create, :destroy] do - get :search_booths, on: :collection - get :manage, on: :collection - end - - resources :officer_assignments, only: [:index, :create, :destroy] do - get :search_officers, on: :collection - get :by_officer, on: :collection - end - - resources :recounts, only: :index - resources :results, only: :index - end - - resources :officers, only: [:index, :new, :create, :destroy] do - get :search, on: :collection - end - - resources :booths do - get :available, on: :collection - - resources :shifts do - get :search_officers, on: :collection - end - end - - resources :questions, shallow: true do - resources :options, except: [:index, :show], controller: "questions/options", shallow: false - resources :options, only: [], controller: "questions/options" do - resources :images, controller: "questions/options/images" - resources :videos, controller: "questions/options/videos", shallow: false - resources :documents, only: [:index, :create], controller: "questions/options/documents" - end - post "/options/order_options", to: "questions/options#order_options" - end - - resource :active_polls, only: [:create, :edit, :update] - end - - resources :verifications, controller: :verifications, only: :index do - get :search, on: :collection - end - - resource :activity, controller: :activity, only: :show - - resources :newsletters do - member do - post :deliver - end - get :users, on: :collection - end - - resources :admin_notifications do - member do - post :deliver - end - end - - resources :system_emails, only: [:index] do - get :view - get :preview_pending - put :moderate_pending - put :send_pending - end - - resources :emails_download, only: :index do - get :generate_csv, on: :collection - end - - resource :stats, only: :show do - get :graph, on: :member - get :budgets, on: :collection - get :budget_supporting, on: :member - get :budget_balloting, on: :member - get :proposal_notifications, on: :collection - get :direct_messages, on: :collection - get :polls, on: :collection - get :sdg, on: :collection - end - - namespace :legislation do - resources :processes do - resources :questions - resources :proposals do - member do - patch :select - patch :deselect - end - end - resources :draft_versions - resources :milestones - resources :progress_bars, except: :show - resource :homepage, only: [:edit, :update] - end - end - - resources :geozones, only: [:index, :new, :create, :edit, :update, :destroy] - resource :locales, only: [:show, :update] - - namespace :site_customization do - resources :pages, except: [:show] do - resources :cards, except: [:show], as: :widget_cards - end - resources :images, only: [:index, :update, :destroy] - resources :content_blocks, except: [:show] - delete "/heading_content_blocks/:id", to: "content_blocks#delete_heading_content_block", - as: "delete_heading_content_block" - get "/edit_heading_content_blocks/:id", to: "content_blocks#edit_heading_content_block", - as: "edit_heading_content_block" - put "/update_heading_content_blocks/:id", to: "content_blocks#update_heading_content_block", - as: "update_heading_content_block" - resources :information_texts, only: [:index] do - post :update, on: :collection - end - resources :documents, only: [:index, :new, :create, :destroy] - end - - resource :homepage, controller: :homepage, only: [:show] - - namespace :widget do - resources :cards - resources :feeds, only: [:update] - end - - namespace :dashboard do - resources :actions, only: [:index, :new, :create, :edit, :update, :destroy] - resources :administrator_tasks, only: [:index, :edit, :update] - end - - resources :local_census_records - namespace :local_census_records do - resources :imports, only: [:new, :create, :show] - end - - resource :machine_learning, controller: :machine_learning, only: [:show] do - post :execute, on: :collection - delete :cancel, on: :collection - end - resources :tenants, except: [:show, :destroy] do member do put :hide put :restore end end + + constraints lambda { |request| !Rails.application.multitenancy_management_mode? } do + resources :organizations, only: :index do + get :search, on: :collection + member do + put :verify + put :reject + end + end + + resources :hidden_users, only: [:index, :show] do + member do + put :restore + put :confirm_hide + end + end + + resources :hidden_budget_investments, only: :index do + member do + put :restore + put :confirm_hide + end + end + + resources :hidden_debates, only: :index do + member do + put :restore + put :confirm_hide + end + end + + resources :debates, only: [:index, :show] + + resources :proposals, only: [:index, :show, :update] do + member do + patch :select + patch :deselect + end + + resources :milestones, controller: "proposal_milestones" + resources :progress_bars, except: :show, controller: "proposal_progress_bars" + end + + resources :hidden_proposals, only: :index do + member do + put :restore + put :confirm_hide + end + end + + resources :hidden_proposal_notifications, only: :index do + member do + put :restore + put :confirm_hide + end + end + + resources :budgets, except: [:create, :new] do + member do + patch :publish + put :calculate_winners + end + + resources :groups, except: [:index, :show], controller: "budget_groups" do + resources :headings, except: [:index, :show], controller: "budget_headings" + end + + resources :budget_investments, only: [:index, :show, :edit, :update] do + member do + patch :select + patch :deselect + patch :show_to_valuators + patch :hide_from_valuators + end + + resources :audits, only: :show, controller: "budget_investment_audits" + resources :milestones, controller: "budget_investment_milestones" + resources :progress_bars, except: :show, controller: "budget_investment_progress_bars" + end + + resources :budget_phases, only: [:edit, :update] do + member do + patch :enable + patch :disable + end + end + end + + namespace :budgets_wizard do + resources :budgets, only: [:create, :new, :edit, :update] do + resources :groups, only: [:index, :create, :edit, :update, :destroy] do + resources :headings, only: [:index, :create, :edit, :update, :destroy] + end + + resources :phases, as: "budget_phases", only: [:index, :edit, :update] do + member do + patch :enable + patch :disable + end + end + end + end + + resources :milestone_statuses, only: [:index, :new, :create, :update, :edit, :destroy] + + resources :signature_sheets, only: [:index, :new, :create, :show] + + resources :banners, only: [:index, :new, :create, :edit, :update, :destroy] do + collection { get :search } + end + + resources :hidden_comments, only: :index do + member do + put :restore + put :confirm_hide + end + end + + resources :comments, only: :index + + resources :tags, only: [:index, :create, :update, :destroy] + + resources :officials, only: [:index, :edit, :update, :destroy] do + get :search, on: :collection + end + + resources :settings, only: [:index, :update] + put :update_map, to: "settings#update_map" + put :update_content_types, to: "settings#update_content_types" + + resources :moderators, only: [:index, :create, :destroy] do + get :search, on: :collection + end + + resources :valuators, only: [:show, :index, :edit, :update, :create, :destroy] do + get :search, on: :collection + get :summary, on: :collection + end + + resources :valuator_groups + + resources :managers, only: [:index, :create, :destroy] do + get :search, on: :collection + end + + namespace :sdg do + resources :managers, only: [:index, :create, :destroy] + end + + resources :users, only: [:index, :show] + + scope module: :poll do + resources :polls do + get :booth_assignments, on: :collection + + resources :booth_assignments, only: [:index, :show, :create, :destroy] do + get :search_booths, on: :collection + get :manage, on: :collection + end + + resources :officer_assignments, only: [:index, :create, :destroy] do + get :search_officers, on: :collection + get :by_officer, on: :collection + end + + resources :recounts, only: :index + resources :results, only: :index + end + + resources :officers, only: [:index, :new, :create, :destroy] do + get :search, on: :collection + end + + resources :booths do + get :available, on: :collection + + resources :shifts do + get :search_officers, on: :collection + end + end + + resources :questions, shallow: true do + resources :options, except: [:index, :show], controller: "questions/options", shallow: false + resources :options, only: [], controller: "questions/options" do + resources :images, controller: "questions/options/images" + resources :videos, controller: "questions/options/videos", shallow: false + resources :documents, only: [:index, :create], controller: "questions/options/documents" + end + post "/options/order_options", to: "questions/options#order_options" + end + + resource :active_polls, only: [:create, :edit, :update] + end + + resources :verifications, controller: :verifications, only: :index do + get :search, on: :collection + end + + resource :activity, controller: :activity, only: :show + + resources :newsletters do + member do + post :deliver + end + get :users, on: :collection + end + + resources :admin_notifications do + member do + post :deliver + end + end + + resources :system_emails, only: [:index] do + get :view + get :preview_pending + put :moderate_pending + put :send_pending + end + + resources :emails_download, only: :index do + get :generate_csv, on: :collection + end + + resource :stats, only: :show do + get :graph, on: :member + get :budgets, on: :collection + get :budget_supporting, on: :member + get :budget_balloting, on: :member + get :proposal_notifications, on: :collection + get :direct_messages, on: :collection + get :polls, on: :collection + get :sdg, on: :collection + end + + namespace :legislation do + resources :processes do + resources :questions + resources :proposals do + member do + patch :select + patch :deselect + end + end + resources :draft_versions + resources :milestones + resources :progress_bars, except: :show + resource :homepage, only: [:edit, :update] + end + end + + resources :geozones, only: [:index, :new, :create, :edit, :update, :destroy] + resource :locales, only: [:show, :update] + + namespace :site_customization do + resources :pages, except: [:show] do + resources :cards, except: [:show], as: :widget_cards + end + resources :images, only: [:index, :update, :destroy] + resources :content_blocks, except: [:show] + delete "/heading_content_blocks/:id", to: "content_blocks#delete_heading_content_block", + as: "delete_heading_content_block" + get "/edit_heading_content_blocks/:id", to: "content_blocks#edit_heading_content_block", + as: "edit_heading_content_block" + put "/update_heading_content_blocks/:id", to: "content_blocks#update_heading_content_block", + as: "update_heading_content_block" + resources :information_texts, only: [:index] do + post :update, on: :collection + end + resources :documents, only: [:index, :new, :create, :destroy] + end + + resource :homepage, controller: :homepage, only: [:show] + + namespace :widget do + resources :cards + resources :feeds, only: [:update] + end + + namespace :dashboard do + resources :actions, only: [:index, :new, :create, :edit, :update, :destroy] + resources :administrator_tasks, only: [:index, :edit, :update] + end + + resources :local_census_records + namespace :local_census_records do + resources :imports, only: [:new, :create, :show] + end + + resource :machine_learning, controller: :machine_learning, only: [:show] do + post :execute, on: :collection + delete :cancel, on: :collection + end + end end resolve "Milestone" do |milestone| diff --git a/config/routes/custom.rb b/config/routes/custom.rb index 8c5264b50..28dc00ba6 100644 --- a/config/routes/custom.rb +++ b/config/routes/custom.rb @@ -26,3 +26,12 @@ # over the default routes. So, if you define a route for `/proposals`, # the default action for `/proposals` will not be used and the one you # define will be used instead. + +constraints lambda { |request| !Rails.application.multitenancy_management_mode? } do + # The routes defined within this block will not be accessible if multitenancy + # management mode is enabled. If you need these routes to be accessible when + # using multitenancy management mode, you should define them outside of this block. + # + # If multitenancy management mode is not being used, routes can be included within + # this block and will still be accessible. +end diff --git a/spec/components/admin/menu_component_spec.rb b/spec/components/admin/menu_component_spec.rb index b05683237..74d13c421 100644 --- a/spec/components/admin/menu_component_spec.rb +++ b/spec/components/admin/menu_component_spec.rb @@ -1,6 +1,6 @@ require "rails_helper" -describe Admin::MenuComponent, controller: Admin::NewslettersController do +describe Admin::MenuComponent, :admin, controller: Admin::NewslettersController do it "disables all buttons when JavaScript isn't available" do render_inline Admin::MenuComponent.new @@ -20,6 +20,17 @@ describe Admin::MenuComponent, controller: Admin::NewslettersController do expect(page).to have_css "button[aria-expanded='false']", exact_text: "Settings" end + it "only renders the multitenancy and administrators sections in multitenancy management mode" do + allow(Rails.application.config).to receive(:multitenancy_management_mode).and_return(true) + + render_inline Admin::MenuComponent.new + + expect(page).to have_css "#admin_menu" + expect(page).to have_link "Multitenancy" + expect(page).to have_link "Administrators" + expect(page).to have_link count: 2 + end + describe "#polls_link" do it "is marked as current when managing poll options", controller: Admin::Poll::Questions::OptionsController do diff --git a/spec/components/layout/admin_header_component_spec.rb b/spec/components/layout/admin_header_component_spec.rb index 62a938369..61170b25e 100644 --- a/spec/components/layout/admin_header_component_spec.rb +++ b/spec/components/layout/admin_header_component_spec.rb @@ -35,4 +35,13 @@ describe Layout::AdminHeaderComponent do expect(page).not_to have_css "[data-toggle]" end end + + it "does not show link to root path when multitenancy_management_mode is enabled" do + allow(Rails.application.config).to receive(:multitenancy_management_mode).and_return(true) + create(:administrator, user: user) + + render_inline Layout::AdminHeaderComponent.new(user) + + expect(page).not_to have_link "Go back to CONSUL" + end end diff --git a/spec/components/layout/admin_login_items_component_spec.rb b/spec/components/layout/admin_login_items_component_spec.rb index 8d1316ec1..964f1df06 100644 --- a/spec/components/layout/admin_login_items_component_spec.rb +++ b/spec/components/layout/admin_login_items_component_spec.rb @@ -15,6 +15,15 @@ describe Layout::AdminLoginItemsComponent do expect(page).not_to be_rendered end + it "is not rendered when multitenancy_management_mode is enabled" do + allow(Rails.application.config).to receive(:multitenancy_management_mode).and_return(true) + user = create(:administrator).user + + render_inline Layout::AdminLoginItemsComponent.new(user) + + expect(page).not_to be_rendered + end + it "shows access to all places except officing to administrators" do user = create(:administrator).user diff --git a/spec/components/layout/footer_component_spec.rb b/spec/components/layout/footer_component_spec.rb index 59cb2cf73..9a078fc23 100644 --- a/spec/components/layout/footer_component_spec.rb +++ b/spec/components/layout/footer_component_spec.rb @@ -13,4 +13,11 @@ describe Layout::FooterComponent do end end end + + it "is not rendered when multitenancy_management_mode is enabled" do + allow(Rails.application.config).to receive(:multitenancy_management_mode).and_return(true) + render_inline Layout::FooterComponent.new + + expect(page).not_to be_rendered + end end diff --git a/spec/components/layout/login_items_component_spec.rb b/spec/components/layout/login_items_component_spec.rb new file mode 100644 index 000000000..eecadd2b2 --- /dev/null +++ b/spec/components/layout/login_items_component_spec.rb @@ -0,0 +1,11 @@ +require "rails_helper" + +describe Layout::LoginItemsComponent do + it "does not show the my activity link when multitenancy_management_mode is enabled" do + allow(Rails.application.config).to receive(:multitenancy_management_mode).and_return(true) + + render_inline Layout::LoginItemsComponent.new(create(:user)) + + expect(page).not_to have_content "My content" + end +end diff --git a/spec/components/layout/notification_item_component_spec.rb b/spec/components/layout/notification_item_component_spec.rb index 086ee817a..7b7777829 100644 --- a/spec/components/layout/notification_item_component_spec.rb +++ b/spec/components/layout/notification_item_component_spec.rb @@ -12,4 +12,11 @@ describe Layout::NotificationItemComponent do expect(page).to be_rendered end + + it "is not rendered when multitenancy_management_mode is enabled" do + allow(Rails.application.config).to receive(:multitenancy_management_mode).and_return(true) + render_inline Layout::NotificationItemComponent.new(create(:user)) + + expect(page).not_to be_rendered + end end diff --git a/spec/components/layout/subnavigation_component_spec.rb b/spec/components/layout/subnavigation_component_spec.rb new file mode 100644 index 000000000..bccca4c05 --- /dev/null +++ b/spec/components/layout/subnavigation_component_spec.rb @@ -0,0 +1,10 @@ +require "rails_helper" + +describe Layout::SubnavigationComponent do + it "is not rendered when multitenancy_management_mode is enabled" do + allow(Rails.application.config).to receive(:multitenancy_management_mode).and_return(true) + render_inline Layout::SubnavigationComponent.new + + expect(page).not_to be_rendered + end +end diff --git a/spec/controllers/users/sessions_controller_spec.rb b/spec/controllers/users/sessions_controller_spec.rb index 5f13ddb10..dc666a5ff 100644 --- a/spec/controllers/users/sessions_controller_spec.rb +++ b/spec/controllers/users/sessions_controller_spec.rb @@ -69,4 +69,22 @@ describe Users::SessionsController do end end end + + describe "after_sign_in_path_for" do + it "redirects to account path when multitenancy_management_mode is enabled and user is not an admin" do + allow(Rails.application.config).to receive(:multitenancy_management_mode).and_return(true) + + post :create, params: { user: { login: "citizen@consul.org", password: "12345678" }} + + expect(response).to redirect_to account_path + end + + it "redirects to welcome path when multitenancy_management_mode is disabled" do + allow(Rails.application.config).to receive(:multitenancy_management_mode).and_return(false) + + post :create, params: { user: { login: "citizen@consul.org", password: "12345678" }} + + expect(response).to redirect_to welcome_path + end + end end diff --git a/spec/system/multitenancy_management_mode_spec.rb b/spec/system/multitenancy_management_mode_spec.rb new file mode 100644 index 000000000..0780cff14 --- /dev/null +++ b/spec/system/multitenancy_management_mode_spec.rb @@ -0,0 +1,28 @@ +require "rails_helper" + +describe "Multitenancy management mode", :admin do + before do + allow(Rails.application.config).to receive(:multitenancy_management_mode).and_return(true) + Setting["org_name"] = "CONSUL" + end + + scenario "renders expected content for multitenancy manage mode in admin section" do + visit admin_root_path + + within ".top-links" do + expect(page).not_to have_content "Go back to CONSUL" + end + + within ".top-bar" do + expect(page).to have_css "li", count: 2 + expect(page).to have_content "My account" + expect(page).to have_content "Sign out" + end + + within "#admin_menu" do + expect(page).to have_content "Multitenancy" + expect(page).to have_content "Administrators" + expect(page).to have_css "li", count: 2 + end + end +end