Skip to content

Commit

Permalink
Merge branch 'production' into frf/robot.txt-exclude-sensitive-paths
Browse files Browse the repository at this point in the history
  • Loading branch information
francois-ferrandis authored Mar 4, 2025
2 parents 861334f + c97a127 commit eddde59
Show file tree
Hide file tree
Showing 67 changed files with 528 additions and 266 deletions.
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -711,7 +711,7 @@ GEM
unicode-emoji (~> 4.0, >= 4.0.4)
unicode-emoji (4.0.4)
uniform_notifier (1.16.0)
uri (0.13.0)
uri (1.0.3)
validate_email (0.1.6)
activemodel (>= 3.0)
mail (>= 2.2.5)
Expand Down
8 changes: 0 additions & 8 deletions app/controllers/admin/organisations_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ class Admin::OrganisationsController < AgentAuthController
respond_to :html, :json

before_action :set_organisation, except: :index
before_action :follow_unique, only: :index

def index
@organisations_by_territory = policy_scope(current_agent.organisations, policy_scope_class: Agent::OrganisationPolicy::Scope)
Expand Down Expand Up @@ -73,11 +72,4 @@ def organisation_params
def new_organisation_params
params.require(:organisation).permit(:name, :territory_id)
end

def follow_unique
accessible_organisations = policy_scope(Organisation, policy_scope_class: Agent::OrganisationPolicy::Scope)
return if params[:follow_unique].blank? || accessible_organisations.count != 1

redirect_to admin_organisation_agent_agenda_path(accessible_organisations.first, current_agent)
end
end
6 changes: 3 additions & 3 deletions app/controllers/admin/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class Admin::UsersController < AgentAuthController
family_situation number_of_children
notify_by_sms notify_by_email
case_number address_details
notes logement ants_pre_demande_number notification_email
logement ants_pre_demande_number notification_email
].freeze

PERMITTED_NESTED_ATTRIBUTES = {
Expand Down Expand Up @@ -51,7 +51,7 @@ def create
prepare_create
authorize(@user, policy_class: Agent::UserPolicy)
@user.skip_confirmation_notification!
user_persisted = @user_form.save
user_persisted = @user_form.save(annotation_content: params.dig(:user, :annotation_content), current_territory:)

if invite_user?(@user, params)
@user.invite!(domain: current_domain)
Expand Down Expand Up @@ -83,7 +83,7 @@ def update
@user.assign_attributes(user_params)
@user_form = user_form_object
@user.skip_reconfirmation! if @user.encrypted_password.blank?
user_updated = @user_form.save
user_updated = @user_form.save(annotation_content: params.dig(:user, :annotation_content), current_territory:)
if from_modal?
respond_modal_with @user_form, location: modal_return_location
elsif user_updated
Expand Down
6 changes: 5 additions & 1 deletion app/controllers/agent_connect_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ def auth
redirect_to auth_client.redirect_url(agent_connect_callback_url), allow_other_host: true
end

def callback
def callback # rubocop:disable Metrics/PerceivedComplexity
callback_client = AgentConnectOpenIdClient::Callback.new(
session_state: session.delete(:agent_connect_state),
params_state: params[:state],
Expand All @@ -33,6 +33,10 @@ def callback
# voir https://github.com/numerique-gouv/agentconnect-documentation/blob/main/doc_fs/donnees_fournies.md#le-champ-sub
agent = Agent.active.find_by(email: callback_client.user_email)

if current_domain.allow_agent_creation_with_agent_connect
agent ||= Agent.new(email: callback_client.user_email, password: SecureRandom.base64(32))
end

if agent
agent.update!(
connected_with_agent_connect: true,
Expand Down
23 changes: 23 additions & 0 deletions app/controllers/agents/pages_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
class Agents::PagesController < AgentAuthController
layout "application"

CONTACT_TEAM_URL = "https://cal.com/forms/937585aa-48a4-4efd-a642-961fad79c9c5".freeze

def home
skip_authorization

accessible_organisations = policy_scope(Organisation, policy_scope_class: Agent::OrganisationPolicy::Scope)

if accessible_organisations.count == 1
redirect_to admin_organisation_agent_agenda_path(accessible_organisations.first, current_agent)
elsif accessible_organisations.count > 1
redirect_to admin_organisations_path
end
end

private

def pundit_user
AgentContext.new(current_agent)
end
end
7 changes: 5 additions & 2 deletions app/controllers/static_pages_controller.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
class StaticPagesController < ApplicationController
def mds
redirect_to root_path unless current_domain == Domain::RDV_SOLIDARITES
render layout: "application_base"
if current_domain == Domain::RDV_SOLIDARITES
render layout: "application_base"
else
redirect_to root_path
end
end

def accessibility; end
Expand Down
11 changes: 10 additions & 1 deletion app/controllers/super_admins/comptes_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
module SuperAdmins
class ComptesController < SuperAdmins::ApplicationController
def new
@agent = Agent.find_by(id: params[:agent_id])
if @agent
authorize_resource(@agent)
end

super
end

def create
compte_params[:agent][:invited_by] = current_super_admin
compte = Compte.new(compte_params, current_domain)
Expand All @@ -24,7 +33,7 @@ def compte_params
territory: %i[name departement_number],
organisation: %i[name ants_connectable],
lieu: %i[address latitude longitude],
agent: %i[first_name last_name email service_ids]
agent: %i[id first_name last_name email service_ids]
)
end
end
Expand Down
11 changes: 9 additions & 2 deletions app/form_models/admin/user_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,15 @@ def valid?
super && user.valid? # order is important here
end

def save
valid? && user.save
def save(annotation_content:, current_territory:)
return false unless valid?

user.transaction do
if user.save
user.annotate!(annotation_content, territory: current_territory)
true
end
end
end

private
Expand Down
22 changes: 18 additions & 4 deletions app/form_models/compte.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,7 @@ def save!
organisation.save!
lieu.save!

self.agent = Agent.invite!(@attributes[:agent].merge(
password: SecureRandom.base64(32),
roles_attributes: [{ organisation: organisation, access_level: AgentRole::ACCESS_LEVEL_ADMIN }]
))
self.agent = find_or_invite_agent(organisation)

agent.services.each do |service|
TerritoryService.create!(service: service, territory: territory)
Expand Down Expand Up @@ -65,6 +62,23 @@ def to_s

private

def find_or_invite_agent(organisation)
if @attributes.dig(:agent, :id)
Agent.find(@attributes.dig(:agent, :id)).tap do |agent|
agent.update(
@attributes[:agent].merge(
roles_attributes: [{ organisation: organisation, access_level: AgentRole::ACCESS_LEVEL_ADMIN }]
)
)
end
else
Agent.invite!(@attributes[:agent].merge(
roles_attributes: [{ organisation: organisation, access_level: AgentRole::ACCESS_LEVEL_ADMIN }],
password: SecureRandom.base64(32)
))
end
end

def create_mairie_motifs!
service = Service.find_by(name: Service::MAIRIE)

Expand Down
6 changes: 5 additions & 1 deletion app/form_models/merge_users_form.rb
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,11 @@ def attributes_to_merge
end

def values_for(attribute)
[user1&.send(attribute), user2&.send(attribute)]
if attribute == :annotation_content
[user1.annotation_for(@organisation.territory), user2.annotation_for(@organisation.territory)]
else
[user1&.send(attribute), user2&.send(attribute)]
end
end

def different_users?
Expand Down
7 changes: 5 additions & 2 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,12 @@ def boolean_attribute_tag(object, attribute_name)
boolean_tag(value) { object.class.human_attribute_value(attribute_name, value) }
end

def object_attribute_tag(object, attribute_name, value = nil)
def object_attribute_tag(object, attribute_name, value = :delegate_to_object)
name = object.class.human_attribute_name(attribute_name)
value ||= object.human_attribute_value(attribute_name)

if value == :delegate_to_object
value = object.human_attribute_value(attribute_name)
end

tag.strong(tag.span(name) + tag.span(" : ")) +
tag.span(value.presence || "Non renseigné", class: class_names("text-muted": value.blank?))
Expand Down
9 changes: 5 additions & 4 deletions app/helpers/users_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,9 @@ def clickable_user_phone_number(user)
user.responsible_phone_number.present? ? link_to(user.responsible_phone_number, "tel:#{user.responsible_or_self.phone_number_formatted}") : nil
end

def formatted_user_notes(user)
user.notes.present? ? simple_format(user.notes) : nil
def formatted_user_annotation(user, current_territory)
annotation = user.annotation_for(current_territory)
annotation.present? ? simple_format(annotation) : nil
end

def user_soft_delete_confirm_message(user)
Expand Down Expand Up @@ -180,10 +181,10 @@ def default_service_selection_from(source)
:responsible
end

def user_merge_attribute_value(user, attribute)
def user_merge_attribute_value(user, attribute, current_territory)
return birth_date_and_age(user) if attribute == :birth_date
return user.responsible&.full_name if attribute == :responsible_id
return formatted_user_notes(user) if attribute == :notes
return formatted_user_annotation(user, current_territory) if attribute == :annotation_content
return user&.human_attribute_value(:logement) if attribute == :logement

user.send(attribute)
Expand Down
4 changes: 4 additions & 0 deletions app/javascript/stylesheets/administrate/base/_forms.scss
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,7 @@ select {
outline-offset: $focus-outline-offset;
}
}

.form-group {
margin: 8px 0;
}
2 changes: 1 addition & 1 deletion app/models/agent.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def timeout_in = 14.days # Used by Devise's :timeoutable
# * it validates :email (the invite_key) specifically with Devise.email_regexp.
validates :first_name, presence: true, unless: -> { allow_blank_name || is_an_intervenant? }
validates :last_name, presence: true, unless: -> { allow_blank_name }
validates :agent_services, presence: true
validates :agent_services, presence: true, unless: -> { roles.none? }

# Hooks
before_destroy :prevent_destroy_if_rdvs
Expand Down
10 changes: 10 additions & 0 deletions app/models/annotation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,14 @@ class Annotation < ApplicationRecord

validates :content, presence: true
validates :territory_id, uniqueness: { scope: :user_id }

def self.upsert!(content, user:, territory:)
if content.present?
annotation = find_or_initialize_by(user:, territory:)
annotation.content = content
annotation.save!
else
find_by(user:, territory:)&.destroy!
end
end
end
4 changes: 4 additions & 0 deletions app/models/domain.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
:support_email,
:secretariat_email,
:verticale,
:allow_agent_creation_with_agent_connect,
keyword_init: true
)

Expand All @@ -36,6 +37,7 @@ class Domain
france_connect_enabled: true,
support_email: "[email protected]",
verticale: :rdv_solidarites,
allow_agent_creation_with_agent_connect: false,
secretariat_email: "[email protected]"
# secretariat_email est utilisé comme adresse de "Reply-To" pour les e-mails
# qui contiennent des ICS. Lorsque l'événement ICS est acceptée par le
Expand All @@ -58,6 +60,7 @@ class Domain
france_connect_enabled: false,
support_email: "[email protected]",
verticale: :rdv_aide_numerique,
allow_agent_creation_with_agent_connect: false,
secretariat_email: "[email protected]"
),

Expand All @@ -76,6 +79,7 @@ class Domain
france_connect_enabled: true,
support_email: "[email protected]",
verticale: :rdv_mairie,
allow_agent_creation_with_agent_connect: true,
secretariat_email: "[email protected]"
),
].freeze
Expand Down
2 changes: 1 addition & 1 deletion app/models/territory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ class Territory < ApplicationRecord
}.freeze

OPTIONAL_FIELD_TOGGLES = {
enable_notes_field: :notes,
enable_notes_field: :annotation_content,
enable_logement_field: :logement,
}.merge(SOCIAL_FIELD_TOGGLES).freeze

Expand Down
36 changes: 9 additions & 27 deletions app/models/user.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
class User < ApplicationRecord
self.ignored_columns += %i[invitations_count]
self.ignored_columns += %i[invitations_count notes]

# Mixins
has_paper_trail(
Expand Down Expand Up @@ -77,8 +77,6 @@ def self.search_options
# Hooks
before_save :set_email_to_null_if_blank
before_save :clear_notification_email_if_email_present
after_create :create_annotations # backfill temporaire, première étape de migration
after_update :sync_annotations # backfill temporaire, première étape de migration

# Scopes
default_scope { where(deleted_at: nil) }
Expand Down Expand Up @@ -265,6 +263,14 @@ def cleanup_annotations
annotations.where.not(territory: territories.reload).each(&:destroy!)
end

def annotation_for(territory)
annotations.find_by(territory: territory)&.content
end

def annotate!(content, territory:)
Annotation.upsert!(content, user: self, territory:)
end

protected

def generate_rdv_invitation_token
Expand Down Expand Up @@ -298,30 +304,6 @@ def set_email_to_null_if_blank
self.email = nil if email.blank?
end

def create_annotations
return if notes.blank?

territories.distinct.map.each do |territory|
annotation = annotations.find_or_initialize_by(territory:)
annotation.content = notes
annotation.save!
end
end

def sync_annotations
return unless notes_previously_changed?

if notes.present?
territories.distinct.map.each do |territory|
annotation = annotations.find_or_initialize_by(territory:)
annotation.content = notes
annotation.save!
end
else
annotations.destroy_all
end
end

def clear_notification_email_if_email_present
self.notification_email = nil if email.present?
end
Expand Down
3 changes: 3 additions & 0 deletions app/services/admin_creates_agent.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ def call
@agent = find_agent

if @agent
if @agent.services.none?
@agent.update(service_ids: @agent_params[:service_ids])
end
add_agent_to_organisations
@warning_message = self.class.check_agent_service(@agent, @agent_params[:service_ids])
elsif @access_level == "intervenant"
Expand Down
Loading

0 comments on commit eddde59

Please sign in to comment.