feat(demarche): create and prefill a dossier with POST request (#8233)

* add base controller for public api

* add dossiers controller with basic checks

* create the dossier

* ensure content-type is json

* prefill dossier with given values

* mark a dossier as prefilled

When a dossier is prefilled, it's allowed not to have a user.

Plus, we add a secure token to the dossier, which we will need later to set a
user after sign in / sign up.

* set user as owner of an orphan prefilled dossier

When a visitor comes from the dossier_url answered by the public api,
the dossier is orphan:
- when the user is already authenticated: they become the owner
- when the user is not authenticated: they can sign in / sign up / france_connect
and then they become the owner

So here is the procedure:
- allow to sign in / sign up / france connect when user is unauthenticated
- set dossier ownership when the dossier is orphan
- check dossier ownership when the dossier is not
- redirect to brouillon path when user is signed in and owner

* mark the dossier as prefilled when it's prefilled
(even with a GET request, because it will be useful later on, for
exmample in order to cleanup the unused prefilled dossiers)

* system spec: prefilling dossier with post request
This commit is contained in:
Sébastien Carceles 2023-01-03 14:46:10 +01:00 committed by GitHub
parent 3f4e7ab1f5
commit 20136b7ac8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
33 changed files with 760 additions and 111 deletions

View file

@ -4,6 +4,10 @@ module Users
layout 'procedure_context'
before_action :retrieve_prefilled_dossier, if: -> { params[:prefill_token].present? }, only: :commencer
before_action :set_prefilled_dossier_ownership, if: -> { user_signed_in? && @prefilled_dossier&.orphan? }, only: :commencer
before_action :check_prefilled_dossier_ownership, if: -> { user_signed_in? && @prefilled_dossier }, only: :commencer
def commencer
@procedure = retrieve_procedure
return procedure_not_found if @procedure.blank? || @procedure.brouillon?
@ -74,6 +78,21 @@ module Users
Procedure.publiees.or(Procedure.brouillons).or(Procedure.closes).find_by(path: params[:path])
end
def retrieve_prefilled_dossier
@prefilled_dossier = Dossier.state_brouillon.prefilled.find_by!(prefill_token: params[:prefill_token])
end
# The prefilled dossier is not owned yet, and the user is signed in: they become the new owner
def set_prefilled_dossier_ownership
@prefilled_dossier.update!(user: current_user)
DossierMailer.with(dossier: @prefilled_dossier).notify_new_draft.deliver_later
end
# The prefilled dossier is owned by another user: raise an exception
def check_prefilled_dossier_ownership
raise ActiveRecord::RecordNotFound unless @prefilled_dossier.owned_by?(current_user)
end
def procedure_not_found
procedure = Procedure.find_by(path: params[:path])
@ -92,7 +111,7 @@ module Users
end
def store_user_location!(procedure)
store_location_for(:user, helpers.procedure_lien(procedure))
store_location_for(:user, helpers.procedure_lien(procedure, prefill_token: params[:prefill_token]))
end
def generate_empty_pdf(revision)

View file

@ -45,7 +45,7 @@ class Users::ConfirmationsController < Devise::ConfirmationsController
end
if procedure_from_params
commencer_path(path: procedure_from_params.path)
commencer_path(path: procedure_from_params.path, prefill_token: params[:prefill_token])
elsif signed_in?
# Will try to use `stored_location_for` to find a path
after_sign_in_path_for(resource_name)

View file

@ -26,6 +26,7 @@ class Users::RegistrationsController < Devise::RegistrationsController
# all Devise code.
# So instead we use a per-request global variable.
CurrentConfirmation.procedure_after_confirmation = @procedure
CurrentConfirmation.prefill_token = @prefill_token
# Handle existing user trying to sign up again
existing_user = User.find_by(email: params[:user][:email])