Permet d'insérer un lien vers MonAvis dans les démarches
This commit is contained in:
commit
9d9509393d
14 changed files with 196 additions and 8 deletions
|
@ -2,7 +2,7 @@ class Admin::ProceduresController < AdminController
|
|||
include SmartListing::Helper::ControllerExtensions
|
||||
helper SmartListing::Helper
|
||||
|
||||
before_action :retrieve_procedure, only: [:show, :edit, :delete_logo, :delete_deliberation, :delete_notice]
|
||||
before_action :retrieve_procedure, only: [:show, :edit, :delete_logo, :delete_deliberation, :delete_notice, :monavis, :update_monavis]
|
||||
|
||||
def index
|
||||
if current_administrateur.procedures.count != 0
|
||||
|
@ -198,6 +198,18 @@ class Admin::ProceduresController < AdminController
|
|||
render layout: 'application'
|
||||
end
|
||||
|
||||
def monavis
|
||||
end
|
||||
|
||||
def update_monavis
|
||||
if !@procedure.update(procedure_params)
|
||||
flash.now.alert = @procedure.errors.full_messages
|
||||
else
|
||||
flash.notice = 'le champ MonAvis a bien été mis à jour'
|
||||
end
|
||||
render 'monavis'
|
||||
end
|
||||
|
||||
def active_class
|
||||
@active_class = 'active'
|
||||
end
|
||||
|
@ -265,7 +277,7 @@ class Admin::ProceduresController < AdminController
|
|||
end
|
||||
|
||||
def procedure_params
|
||||
editable_params = [:libelle, :description, :organisation, :direction, :lien_site_web, :cadre_juridique, :deliberation, :notice, :web_hook_url, :euro_flag, :logo, :auto_archive_on]
|
||||
editable_params = [:libelle, :description, :organisation, :direction, :lien_site_web, :cadre_juridique, :deliberation, :notice, :web_hook_url, :euro_flag, :logo, :auto_archive_on, :monavis_embed]
|
||||
if @procedure&.locked?
|
||||
params.require(:procedure).permit(*editable_params)
|
||||
else
|
||||
|
|
|
@ -71,7 +71,7 @@ class Procedure < ApplicationRecord
|
|||
validates :duree_conservation_dossiers_hors_ds, allow_nil: false, numericality: { only_integer: true, greater_than_or_equal_to: 0 }, if: :durees_conservation_required
|
||||
validates :duree_conservation_dossiers_dans_ds, allow_nil: true, numericality: { only_integer: true, greater_than_or_equal_to: 1, less_than_or_equal_to: MAX_DUREE_CONSERVATION }, unless: :durees_conservation_required
|
||||
validates :duree_conservation_dossiers_hors_ds, allow_nil: true, numericality: { only_integer: true, greater_than_or_equal_to: 0 }, unless: :durees_conservation_required
|
||||
|
||||
validates_with MonAvisEmbedValidator
|
||||
before_save :update_juridique_required
|
||||
before_save :update_durees_conservation_required
|
||||
before_create :ensure_path_exists
|
||||
|
|
9
app/validators/mon_avis_embed_validator.rb
Normal file
9
app/validators/mon_avis_embed_validator.rb
Normal file
|
@ -0,0 +1,9 @@
|
|||
class MonAvisEmbedValidator < ActiveModel::Validator
|
||||
def validate(record)
|
||||
# We need to ensure the embed code is not any random string in order to avoid injections
|
||||
r = Regexp.new('<a href="https://monavis.numerique.gouv.fr/Demarches/\d+.*key=[[:alnum:]]+.*">\s*<img src="https://monavis.numerique.gouv.fr/monavis-static/bouton-blanc|bleu.png" alt="Je donne mon avis" title="Je donne mon avis sur cette démarche" />\s*</a>', Regexp::MULTILINE)
|
||||
if record.monavis_embed.present? && !r.match?(record.monavis_embed)
|
||||
record.errors[:base] << "Le code fourni ne correspond pas au format des codes MonAvis reconnus par la plateforme."
|
||||
end
|
||||
end
|
||||
end
|
16
app/views/admin/procedures/_monavis.html.haml
Normal file
16
app/views/admin/procedures/_monavis.html.haml
Normal file
|
@ -0,0 +1,16 @@
|
|||
.form-group
|
||||
%h3 Insérer un lien vers « MonAvis »
|
||||
%p
|
||||
Proposez aux usagers de donner un avis sur votre démarche. Pour ce faire, vous devez précédemment aller sur «
|
||||
%a{ :href => "https://monavis.numerique.gouv.fr" } https://monavis.numerique.gouv.fr
|
||||
», créer un compte, et référencer là démarche que vous venez de publier.
|
||||
|
||||
%p
|
||||
Dès que vous avez effectué le référencement de celle-ci, vous pouvez suivre le guide d’intégration du bouton que vous trouverez à
|
||||
%a{ :href => "https://monavis.numerique.gouv.fr/Aide/Int%C3%A9gration%20du%20bouton%20MonAvis" } l’adresse suivante.
|
||||
|
||||
%p Une fois en possession du code généré sur le site MonAvis, vous pouvez le coller dans le champ ci-dessous :
|
||||
|
||||
.form-group
|
||||
= f.label :monavis_embed, "Mon avis"
|
||||
= f.text_area :monavis_embed, rows: '6', placeholder: '<a href="https://monavis.numerique.gouv.fr/Demarches/123456?&view-mode=formulaire-avis&nd_mode=en-ligne-enti%C3%A8rement&nd_source=button&key=cd4a872d4"><img src="https://monavis.numerique.gouv.fr/monavis-static/bouton-bleu.png" alt="Je donne mon avis" title="Je donne mon avis sur cette démarche" /></a>', class: 'form-control'
|
6
app/views/admin/procedures/monavis.html.haml
Normal file
6
app/views/admin/procedures/monavis.html.haml
Normal file
|
@ -0,0 +1,6 @@
|
|||
.row.white-back
|
||||
#procedure_new.section.section-label
|
||||
= form_for @procedure, url: url_for({ controller: 'admin/procedures', action: :update_monavis, id: @procedure.id }), multipart: true do |f|
|
||||
= render partial: 'monavis', locals: { f: f }
|
||||
.text-right
|
||||
= f.button 'Enregistrer', class: 'btn btn-success'
|
|
@ -0,0 +1 @@
|
|||
= render partial: 'layouts/left_panels/left_panel_admin_procedurescontroller_navbar', locals: { active: 'MonAvis' }
|
|
@ -64,6 +64,10 @@
|
|||
.procedure-list-element{ class: ('active' if active == 'Attestation') }
|
||||
Attestation
|
||||
|
||||
%a#onglet-description{ href: url_for(admin_procedure_monavis_path(@procedure)) }
|
||||
.procedure-list-element{ class: ('active' if active == 'MonAvis') }
|
||||
MonAvis
|
||||
|
||||
.split-hr-left
|
||||
|
||||
|
||||
|
|
|
@ -23,3 +23,4 @@
|
|||
.flex.column.align-center
|
||||
= link_to 'Accéder à votre dossier', dossier_path(@dossier), class: 'button large primary'
|
||||
= link_to 'Déposer un autre dossier', procedure_lien(@dossier.procedure)
|
||||
!= @dossier.procedure.monavis_embed
|
||||
|
|
|
@ -1,5 +1,24 @@
|
|||
{
|
||||
"ignored_warnings": [
|
||||
{
|
||||
"warning_type": "Cross-Site Scripting",
|
||||
"warning_code": 2,
|
||||
"fingerprint": "483ae8c038244eb3ed709e89846335e2c8ff6579260348ec31d3d03d1c94ad64",
|
||||
"check_name": "CrossSiteScripting",
|
||||
"message": "Unescaped model attribute",
|
||||
"file": "app/views/users/dossiers/merci.html.haml",
|
||||
"line": 26,
|
||||
"link": "https://brakemanscanner.org/docs/warning_types/cross_site_scripting",
|
||||
"code": "current_user.dossiers.includes(:procedure).find(params[:id]).procedure.monavis_embed",
|
||||
"render_path": [{"type":"controller","class":"Users::DossiersController","method":"merci","line":178,"file":"app/controllers/users/dossiers_controller.rb"}],
|
||||
"location": {
|
||||
"type": "template",
|
||||
"template": "users/dossiers/merci"
|
||||
},
|
||||
"user_input": "current_user.dossiers.includes(:procedure)",
|
||||
"confidence": "Weak",
|
||||
"note": ""
|
||||
},
|
||||
{
|
||||
"warning_type": "SQL Injection",
|
||||
"warning_code": 0,
|
||||
|
@ -27,7 +46,7 @@
|
|||
"check_name": "SQL",
|
||||
"message": "Possible SQL injection",
|
||||
"file": "app/models/procedure_presentation.rb",
|
||||
"line": 97,
|
||||
"line": 98,
|
||||
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
||||
"code": "((\"self\" == \"self\") ? (dossiers) : (dossiers.includes(\"self\"))).order(\"#{self.class.sanitized_column(\"self\", column)} #{order}\")",
|
||||
"render_path": null,
|
||||
|
@ -47,7 +66,7 @@
|
|||
"check_name": "SQL",
|
||||
"message": "Possible SQL injection",
|
||||
"file": "app/models/procedure_presentation.rb",
|
||||
"line": 93,
|
||||
"line": 94,
|
||||
"link": "https://brakemanscanner.org/docs/warning_types/sql_injection/",
|
||||
"code": "dossiers.includes(((\"type_de_champ\" == \"type_de_champ\") ? (:champs) : (:champs_private))).where(\"champs.type_de_champ_id = #{column.to_i}\").order(\"champs.value #{order}\")",
|
||||
"render_path": null,
|
||||
|
@ -61,6 +80,6 @@
|
|||
"note": "`column` and `order` come from the model, which is validated to prevent injection attacks. Furthermore, the sql injection attack on `column` would need to survive the `to_i`"
|
||||
}
|
||||
],
|
||||
"updated": "2019-03-04 11:59:49 +0100",
|
||||
"updated": "2019-07-17 16:03:11 +0200",
|
||||
"brakeman_version": "4.3.1"
|
||||
}
|
||||
|
|
|
@ -206,6 +206,8 @@ Rails.application.routes.draw do
|
|||
put 'publish' => 'procedures#publish', as: :publish
|
||||
post 'transfer' => 'procedures#transfer', as: :transfer
|
||||
put 'clone' => 'procedures#clone', as: :clone
|
||||
get 'monavis' => 'procedures#monavis', as: :monavis
|
||||
patch 'monavis' => 'procedures#update_monavis', as: :update_monavis
|
||||
|
||||
resource :instructeurs, only: [:show, :update]
|
||||
|
||||
|
|
5
db/migrate/20190717132452_add_monavis_to_procedures.rb
Normal file
5
db/migrate/20190717132452_add_monavis_to_procedures.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
class AddMonavisToProcedures < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :procedures, :monavis_embed, :text
|
||||
end
|
||||
end
|
|
@ -10,7 +10,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 2019_07_11_135457) do
|
||||
ActiveRecord::Schema.define(version: 2019_07_17_132452) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
@ -500,6 +500,7 @@ ActiveRecord::Schema.define(version: 2019_07_11_135457) do
|
|||
t.boolean "durees_conservation_required", default: true
|
||||
t.string "path"
|
||||
t.string "declarative_with_state"
|
||||
t.text "monavis_embed"
|
||||
t.index ["declarative_with_state"], name: "index_procedures_on_declarative_with_state"
|
||||
t.index ["hidden_at"], name: "index_procedures_on_hidden_at"
|
||||
t.index ["parent_procedure_id"], name: "index_procedures_on_parent_procedure_id"
|
||||
|
|
|
@ -14,6 +14,7 @@ describe Admin::ProceduresController, type: :controller do
|
|||
let(:cadre_juridique) { 'cadre juridique' }
|
||||
let(:duree_conservation_dossiers_dans_ds) { 3 }
|
||||
let(:duree_conservation_dossiers_hors_ds) { 6 }
|
||||
let(:monavis_embed) { nil }
|
||||
|
||||
let(:procedure_params) {
|
||||
{
|
||||
|
@ -24,7 +25,8 @@ describe Admin::ProceduresController, type: :controller do
|
|||
direction: direction,
|
||||
cadre_juridique: cadre_juridique,
|
||||
duree_conservation_dossiers_dans_ds: duree_conservation_dossiers_dans_ds,
|
||||
duree_conservation_dossiers_hors_ds: duree_conservation_dossiers_hors_ds
|
||||
duree_conservation_dossiers_hors_ds: duree_conservation_dossiers_hors_ds,
|
||||
monavis_embed: monavis_embed
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -745,4 +747,77 @@ describe Admin::ProceduresController, type: :controller do
|
|||
}
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PATCH #monavis' do
|
||||
let!(:procedure) { create(:procedure, :with_type_de_champ, :with_two_type_de_piece_justificative, administrateur: admin) }
|
||||
let(:procedure_params) {
|
||||
{
|
||||
monavis_embed: monavis_embed
|
||||
}
|
||||
}
|
||||
|
||||
context 'when administrateur is not connected' do
|
||||
before do
|
||||
sign_out admin
|
||||
end
|
||||
|
||||
subject { patch :update_monavis, params: { procedure_id: procedure.id } }
|
||||
|
||||
it { is_expected.to redirect_to new_user_session_path }
|
||||
end
|
||||
|
||||
context 'when administrateur is connected' do
|
||||
def update_monavis
|
||||
patch :update_monavis, params: { procedure_id: procedure.id, procedure: procedure_params }
|
||||
procedure.reload
|
||||
end
|
||||
let(:monavis_embed) {
|
||||
<<-MSG
|
||||
<a href="https://monavis.numerique.gouv.fr/Demarches/123?&view-mode=formulaire-avis&nd_mode=en-ligne-enti%C3%A8rement&nd_source=button&key=cd4a872d475e4045666057f">
|
||||
<img src="https://monavis.numerique.gouv.fr/monavis-static/bouton-blanc.png" alt="Je donne mon avis" title="Je donne mon avis sur cette démarche" />
|
||||
</a>
|
||||
MSG
|
||||
}
|
||||
|
||||
context 'when all attributes are present' do
|
||||
render_views
|
||||
|
||||
before { update_monavis }
|
||||
|
||||
context 'when the embed code is valid' do
|
||||
describe 'the monavis field is updated' do
|
||||
subject { procedure }
|
||||
|
||||
it { expect(subject.monavis_embed).to eq(monavis_embed) }
|
||||
end
|
||||
|
||||
it { expect(flash[:notice]).to be_present }
|
||||
it { expect(response.body).to include "MonAvis" }
|
||||
end
|
||||
|
||||
context 'when the embed code is not valid' do
|
||||
let(:monavis_embed) { 'invalid embed code' }
|
||||
|
||||
describe 'the monavis field is not updated' do
|
||||
subject { procedure }
|
||||
|
||||
it { expect(subject.monavis_embed).to eq(nil) }
|
||||
end
|
||||
|
||||
it { expect(flash[:alert]).to be_present }
|
||||
it { expect(response.body).to include "MonAvis" }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when procedure is published' do
|
||||
let(:procedure) { create(:procedure, :with_type_de_champ, :with_two_type_de_piece_justificative, :published, administrateur: admin) }
|
||||
|
||||
subject { update_monavis }
|
||||
|
||||
describe 'the monavis field is not updated' do
|
||||
it { expect(subject.monavis_embed).to eq monavis_embed }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -198,6 +198,43 @@ describe Procedure do
|
|||
it { expect(procedure.valid?).to eq(true) }
|
||||
end
|
||||
|
||||
context 'monavis' do
|
||||
context 'nil is allowed' do
|
||||
it { is_expected.to allow_value(nil).for(:monavis_embed) }
|
||||
it { is_expected.to allow_value('').for(:monavis_embed) }
|
||||
end
|
||||
|
||||
context 'random string is not allowed' do
|
||||
let(:procedure) { build(:procedure, monavis_embed: "plop") }
|
||||
it { expect(procedure.valid?).to eq(false) }
|
||||
end
|
||||
|
||||
context 'random html is not allowed' do
|
||||
let(:procedure) { build(:procedure, monavis_embed: '<img src="http://some.analytics/hello.gif">') }
|
||||
it { expect(procedure.valid?).to eq(false) }
|
||||
end
|
||||
|
||||
context 'Monavis embed code with white button is allowed' do
|
||||
monavis_blanc = <<-MSG
|
||||
<a href="https://monavis.numerique.gouv.fr/Demarches/123?&view-mode=formulaire-avis&nd_mode=en-ligne-enti%C3%A8rement&nd_source=button&key=cd4a872d475e4045666057f">
|
||||
<img src="https://monavis.numerique.gouv.fr/monavis-static/bouton-blanc.png" alt="Je donne mon avis" title="Je donne mon avis sur cette démarche" />
|
||||
</a>
|
||||
MSG
|
||||
let(:procedure) { build(:procedure, monavis_embed: monavis_blanc) }
|
||||
it { expect(procedure.valid?).to eq(true) }
|
||||
end
|
||||
|
||||
context 'Monavis embed code with blue button is allowed' do
|
||||
monavis_bleu = <<-MSG
|
||||
<a href="https://monavis.numerique.gouv.fr/Demarches/123?&view-mode=formulaire-avis&nd_mode=en-ligne-enti%C3%A8rement&nd_source=button&key=cd4a872d475e4045666057f">
|
||||
<img src="https://monavis.numerique.gouv.fr/monavis-static/bouton-bleu.png" alt="Je donne mon avis" title="Je donne mon avis sur cette démarche" />
|
||||
</a>
|
||||
MSG
|
||||
let(:procedure) { build(:procedure, monavis_embed: monavis_bleu) }
|
||||
it { expect(procedure.valid?).to eq(true) }
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'duree de conservation' do
|
||||
context 'duree_conservation_required it true, the field gets validated' do
|
||||
before { subject.durees_conservation_required = true }
|
||||
|
|
Loading…
Reference in a new issue