From b6a2aae97041a82fced56ea1d6475d1a2ac70c27 Mon Sep 17 00:00:00 2001 From: Alex Turchyn Date: Tue, 10 Dec 2024 23:18:07 +0200 Subject: [PATCH] restrict user invites --- app/controllers/users_controller.rb | 19 +++------------ config/locales/i18n.yml | 6 +++++ spec/factories/accounts.rb | 15 ++++++++++++ spec/rails_helper.rb | 4 +++ spec/system/team_settings_spec.rb | 38 +++++++++++++++++++++++++++++ 5 files changed, 67 insertions(+), 15 deletions(-) diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index d11e9ba8..4a195104 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -24,14 +24,10 @@ class UsersController < ApplicationController def edit; end def create - existing_user = User.accessible_by(current_ability).find_by(email: @user.email) + if User.accessible_by(current_ability).exists?(email: @user.email) + @user.errors.add(:email, I18n.t('already_exists')) - if existing_user - existing_user.archived_at = nil - existing_user.assign_attributes(user_params) - existing_user.account = current_account - - @user = existing_user + return render turbo_stream: turbo_stream.replace(:modal, template: 'users/new'), status: :unprocessable_entity end @user.role = User::ADMIN_ROLE unless role_valid?(@user.role) @@ -83,14 +79,7 @@ class UsersController < ApplicationController end def build_user - @user = current_account.users.find_by(email: user_params[:email])&.tap do |user| - user.assign_attributes(user_params) - user.archived_at = nil - end - - @user ||= current_account.users.new(user_params) - - @user + @user = current_account.users.new(user_params) end def user_params diff --git a/config/locales/i18n.yml b/config/locales/i18n.yml index 87c69fcd..3e142f59 100644 --- a/config/locales/i18n.yml +++ b/config/locales/i18n.yml @@ -660,6 +660,7 @@ en: &en policy_links: Policy Links markdown_content_e_g: Markdown content, e.g. privacy_policy: Privacy Policy + use_the_edit_form_to_move_it_to_another_team: Use the edit form to move it to another team. submission_event_names: send_email_to_html: 'Email sent to %{submitter_name}' send_reminder_email_to_html: 'Reminder email sent to %{submitter_name}' @@ -1340,6 +1341,7 @@ es: &es policy_links: Enlaces de Políticas markdown_content_e_g: Contenido Markdown, por ej. privacy_policy: Política de Privacidad + use_the_edit_form_to_move_it_to_another_team: Usa el formulario de edición para moverlo a otro equipo. submission_event_names: send_email_to_html: 'Correo electrónico enviado a %{submitter_name}' send_reminder_email_to_html: 'Correo de recordatorio enviado a %{submitter_name}' @@ -2020,6 +2022,7 @@ it: &it policy_links: Collegamenti alle Politiche markdown_content_e_g: Contenuto Markdown, ad es. privacy_policy: Politica sulla Privacy + use_the_edit_form_to_move_it_to_another_team: Usa il modulo di modifica per spostarlo in un altro team. submission_event_names: send_email_to_html: 'E-mail inviato a %{submitter_name}' send_reminder_email_to_html: 'E-mail di promemoria inviato a %{submitter_name}' @@ -2701,6 +2704,7 @@ fr: &fr policy_links: Liens des Politiques markdown_content_e_g: Contenu Markdown, par ex. privacy_policy: Politique de Confidentialité + use_the_edit_form_to_move_it_to_another_team: Utilisez le formulaire de modification pour le déplacer vers une autre équipe. submission_event_names: send_email_to_html: 'E-mail envoyé à %{submitter_name}' send_reminder_email_to_html: 'E-mail de rappel envoyé à %{submitter_name}' @@ -3381,6 +3385,7 @@ pt: &pt policy_links: Links de Políticas markdown_content_e_g: Conteúdo Markdown, ex. privacy_policy: Política de Privacidade + use_the_edit_form_to_move_it_to_another_team: Use o formulário de edição para movê-lo para outra equipe. submission_event_names: send_email_to_html: 'E-mail enviado para %{submitter_name}' send_reminder_email_to_html: 'E-mail de lembrete enviado para %{submitter_name}' @@ -4061,6 +4066,7 @@ de: &de policy_links: Richtlinien-Links markdown_content_e_g: Markdown-Inhalt, z. B. privacy_policy: Datenschutzrichtlinie + use_the_edit_form_to_move_it_to_another_team: Verwenden Sie das Bearbeitungsformular, um ihn in ein anderes Team zu verschieben. submission_event_names: send_email_to_html: 'E-Mail gesendet an %{submitter_name}' send_reminder_email_to_html: 'Erinnerungs-E-Mail gesendet an %{submitter_name}' diff --git a/spec/factories/accounts.rb b/spec/factories/accounts.rb index b0551e06..6a5229bf 100644 --- a/spec/factories/accounts.rb +++ b/spec/factories/accounts.rb @@ -6,6 +6,10 @@ FactoryBot.define do locale { 'en-US' } timezone { 'UTC' } + transient do + teams_count { 2 } + end + trait :with_testing_account do after(:create) do |account| testing_account = account.dup.tap { |a| a.name = "Testing - #{account.name}" } @@ -14,5 +18,16 @@ FactoryBot.define do account.save! end end + + trait :with_teams do + after(:create) do |account, evaluator| + Array.new(evaluator.teams_count) do |i| + Account.create!( + name: "Team #{i}", + linked_account_account: AccountLinkedAccount.new(account_type: :linked, account:) + ) + end + end + end end end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 1157da61..e2195ceb 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -68,6 +68,10 @@ RSpec.configure do |config| config.before do |example| Sidekiq::Testing.inline! if example.metadata[:sidekiq] == :inline end + + config.before(multitenant: true) do + allow(Docuseal).to receive(:multitenant?).and_return(true) + end end ActiveSupport.run_load_hooks(:rails_specs, self) diff --git a/spec/system/team_settings_spec.rb b/spec/system/team_settings_spec.rb index 3472917a..077c5104 100644 --- a/spec/system/team_settings_spec.rb +++ b/spec/system/team_settings_spec.rb @@ -4,6 +4,7 @@ require 'rails_helper' RSpec.describe 'Team Settings' do let(:account) { create(:account) } + let(:second_account) { create(:account) } let(:current_user) { create(:user, account:) } before do @@ -56,6 +57,43 @@ RSpec.describe 'Team Settings' do end end + it "doesn't create a new user if a user already exists" do + click_link 'New User' + + within '#modal' do + fill_in 'First name', with: 'Michael' + fill_in 'Last name', with: 'Jordan' + fill_in 'Email', with: users.first.email + fill_in 'Password', with: 'password' + + expect do + click_button 'Submit' + end.not_to change(User, :count) + end + + expect(page).to have_content('Email already exists') + end + + it "doesn't create a new user if a user belongs to another account" do + user = create(:user, account: second_account) + visit settings_users_path + + click_link 'New User' + + within '#modal' do + fill_in 'First name', with: 'Michael' + fill_in 'Last name', with: 'Jordan' + fill_in 'Email', with: user.email + fill_in 'Password', with: 'password' + + expect do + click_button 'Submit' + end.not_to change(User, :count) + + expect(page).to have_content('Email has already been taken') + end + end + it 'updates a user' do first(:link, 'Edit').click