diff --git a/app/controllers/administrateurs/activate_controller.rb b/app/controllers/administrateurs/activate_controller.rb index cb9394292..6304ddf7e 100644 --- a/app/controllers/administrateurs/activate_controller.rb +++ b/app/controllers/administrateurs/activate_controller.rb @@ -25,13 +25,13 @@ class Administrateurs::ActivateController < ApplicationController reset_password_token: update_administrateur_params[:reset_password_token] }) - if user&.administrateur&.errors&.empty? + if user&.errors&.empty? sign_in(user, scope: :user) flash.notice = "Mot de passe enregistré" redirect_to admin_procedures_path else - flash.alert = user.administrateur.errors.full_messages + flash.alert = user.errors.full_messages redirect_to admin_activate_path(token: update_administrateur_params[:reset_password_token]) end end diff --git a/app/controllers/gestionnaires/activate_controller.rb b/app/controllers/gestionnaires/activate_controller.rb new file mode 100644 index 000000000..c1db0d8e8 --- /dev/null +++ b/app/controllers/gestionnaires/activate_controller.rb @@ -0,0 +1,52 @@ +class Gestionnaires::ActivateController < ApplicationController + include TrustedDeviceConcern + + def new + @token = params[:token] + + user = User.with_reset_password_token(@token) + @gestionnaire = user&.gestionnaire + + if @gestionnaire + # the gestionnaire activates its account from an email + trust_device(Time.zone.now) + else + flash.alert = "Le lien de validation de gestionnaire a expiré, #{helpers.contact_link('contactez-nous', tags: 'lien expiré')} pour obtenir un nouveau lien." + redirect_to root_path + end + end + + def create + password = update_gestionnaire_params[:password] + + user = User.reset_password_by_token({ + password: password, + password_confirmation: password, + reset_password_token: update_gestionnaire_params[:reset_password_token] + }) + + if user&.errors&.empty? + sign_in(user, scope: :user) + + flash.notice = "Mot de passe enregistré" + redirect_to gestionnaire_groupe_gestionnaires_path + else + flash.alert = user.errors.full_messages + redirect_to gestionnaires_activate_path(token: update_gestionnaire_params[:reset_password_token]) + end + end + + private + + def update_gestionnaire_params + params.require(:gestionnaire).permit(:reset_password_token, :password) + end + + def try_to_authenticate(klass, email, password) + resource = klass.find_for_database_authentication(email: email) + + if resource&.valid_password?(password) + sign_in resource + end + end +end diff --git a/app/views/gestionnaires/activate/new.html.haml b/app/views/gestionnaires/activate/new.html.haml new file mode 100644 index 000000000..c020d67bc --- /dev/null +++ b/app/views/gestionnaires/activate/new.html.haml @@ -0,0 +1,26 @@ +- content_for(:title, t('.title')) + +- content_for :footer do + = render partial: "root/footer" + +.fr-container.fr-my-5w + .fr-grid-row.fr-grid-row--center + .fr-col-lg-6 + = form_for @gestionnaire, url: { controller: 'gestionnaires/activate', action: :create } do |f| + = f.hidden_field :reset_password_token, value: @token + + %fieldset.fr-mb-0.fr-fieldset{ aria: { labelledby: 'edit-password-legend' } } + %legend.fr-fieldset__legend#edit-password-legend + %h1.fr-h2= t('.title') + + .fr-fieldset__element + = render Dsfr::InputComponent.new(form: f, attribute: :email, opts: { disabled: true }) + + .fr-fieldset__element + = render Dsfr::InputComponent.new(form: f, attribute: :password, input_type: :password_field, + opts: { autofocus: 'true', autocomplete: 'new-password', data: { controller: 'turbo-input', turbo_input_url_value: show_password_complexity_path }}) + + #password_complexity + = render PasswordComplexityComponent.new + + = f.submit t('.continue'), id: 'submit-password', class: "fr-btn fr-btn--lg fr-mt-2w", data: { disable_with: t('views.users.passwords.edit.submit_loading') } diff --git a/app/views/user_mailer/invite_gestionnaire.html.haml b/app/views/user_mailer/invite_gestionnaire.html.haml index 578e6777b..267f2add4 100644 --- a/app/views/user_mailer/invite_gestionnaire.html.haml +++ b/app/views/user_mailer/invite_gestionnaire.html.haml @@ -8,6 +8,6 @@ %p Votre compte a été créé pour l'adresse email #{@user.email}. Pour l’activer, nous vous invitons à cliquer sur le lien suivant :  - = link_to(users_activate_url(token: @reset_password_token), users_activate_url(token: @reset_password_token)) + = link_to(gestionnaires_activate_url(token: @reset_password_token), gestionnaires_activate_url(token: @reset_password_token)) = render partial: "layouts/mailers/signature" diff --git a/config/locales/en.yml b/config/locales/en.yml index e72cd0a1c..9f06600b3 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -797,6 +797,11 @@ en: updated_at: updated at closed_at: closed at auto_archive_on: will close at + gestionnaires: + activate: + new: + title: Pick a password + continue: Continue users: dossiers: test_procedure: "This file is submitted on a test procedure. Any modification of the procedure by the administrator (addition of a field, publication of the procedure, etc.) will result in the removal of the file." diff --git a/config/locales/fr.yml b/config/locales/fr.yml index f25ffbf20..c32ff20a9 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -895,6 +895,11 @@ fr: explication_html: "

API Particulier facilite l’accès des administrations aux données familiales (CAF), aux données fiscales (DGFiP), au statut pôle-emploi et au statut étudiant d’un citoyen pour simplifier les démarches administratives mises en œuvre par les collectivités et les administrations.
Cela permet aux administrations d’accéder à des informations certifiées à la source et ainsi :

Important : les disposition de l’article L144-8 n’autorisent que l’échange des informations strictement nécessaires pour traiter une démarche.

En conséquence, ne sélectionnez ici que les données auxquelles vous aurez accès d’un point de vue légal.

" update: sources_ok: 'Mise à jour effectuée' + gestionnaires: + activate: + new: + title: Choix du mot de passe + continue: Continuer zones: ministeres: Ministères france_connect: diff --git a/config/routes.rb b/config/routes.rb index 8d6ad9295..77a8e89d9 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -517,6 +517,11 @@ Rails.application.routes.draw do resources :commentaires, controller: 'groupe_gestionnaire_commentaires', only: [:index, :show, :create, :destroy] end end + + namespace :gestionnaires do + get 'activate' => '/gestionnaires/activate#new' + patch 'activate' => '/gestionnaires/activate#create' + end end # diff --git a/spec/controllers/administrateurs/activate_controller_spec.rb b/spec/controllers/administrateurs/activate_controller_spec.rb index 6b97bfe4a..b1f0ee627 100644 --- a/spec/controllers/administrateurs/activate_controller_spec.rb +++ b/spec/controllers/administrateurs/activate_controller_spec.rb @@ -17,4 +17,31 @@ describe Administrateurs::ActivateController, type: :controller do it { expect(controller).not_to have_received(:trust_device) } end end + + describe '#create' do + let!(:administrateur) { create(:administrateur) } + let(:token) { administrateur.user.send(:set_reset_password_token) } + let(:password) { 'Another-password-ok!@#123?' } + + before { post :create, params: { administrateur: { reset_password_token: token, password: password } } } + + context 'when the token is ok' do + it { expect(administrateur.user.reload.valid_password?(password)).to be true } + it { expect(response).to redirect_to(admin_procedures_path) } + end + + context 'when the password is not strong' do + let(:password) { 'another-password-ok?' } + + it { expect(administrateur.user.reload.valid_password?(password)).to be false } + it { expect(response).to redirect_to(admin_activate_path(token: token)) } + end + + context 'when the token is bad' do + let(:token) { 'bad' } + + it { expect(administrateur.user.reload.valid_password?(password)).to be false } + it { expect(response).to redirect_to(admin_activate_path(token: token)) } + end + end end diff --git a/spec/controllers/gestionnaires/activate_controller_spec.rb b/spec/controllers/gestionnaires/activate_controller_spec.rb new file mode 100644 index 000000000..c2fc2ad46 --- /dev/null +++ b/spec/controllers/gestionnaires/activate_controller_spec.rb @@ -0,0 +1,40 @@ +describe Gestionnaires::ActivateController, type: :controller do + describe '#new' do + let(:gestionnaire) { create(:gestionnaire) } + let(:token) { gestionnaire.user.send(:set_reset_password_token) } + + before { allow(controller).to receive(:trust_device) } + + context 'when the token is ok' do + before { get :new, params: { token: token } } + + it { expect(controller).to have_received(:trust_device) } + end + + context 'when the token is bad' do + before { get :new, params: { token: 'bad' } } + + it { expect(controller).not_to have_received(:trust_device) } + end + end + + describe '#create' do + let!(:gestionnaire) { create(:gestionnaire) } + let(:token) { gestionnaire.user.send(:set_reset_password_token) } + let(:password) { 'another-password-ok?' } + + before { post :create, params: { gestionnaire: { reset_password_token: token, password: password } } } + + context 'when the token is ok' do + it { expect(gestionnaire.user.reload.valid_password?(password)).to be true } + it { expect(response).to redirect_to(gestionnaire_groupe_gestionnaires_path) } + end + + context 'when the token is bad' do + let(:token) { 'bad' } + + it { expect(gestionnaire.user.reload.valid_password?(password)).to be false } + it { expect(response).to redirect_to(gestionnaires_activate_path(token: token)) } + end + end +end