Skip to content

Commit

Permalink
Merge pull request #484 from slovensko-digital/GO-49/do_not_submit_dr…
Browse files Browse the repository at this point in the history
…afts_without_requested_signatures

GO-49 Do not submit message unless requested signatures present
  • Loading branch information
luciajanikova authored Oct 29, 2024
2 parents 2f187cf + 181e9b1 commit 5562e60
Show file tree
Hide file tree
Showing 18 changed files with 122 additions and 22 deletions.
7 changes: 6 additions & 1 deletion app/controllers/api/messages_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ def message_drafts
@message.save

permitted_message_draft_params.fetch(:objects, []).each do |object_params|
message_object = @message.objects.create(object_params.except(:content, :tags))
message_object = @message.objects.create(object_params.except(:content, :to_be_signed, :tags))

object_params.fetch(:tags, []).each do |tag_name|
tag = @tenant.user_signature_tags.find_by(name: tag_name)
Expand All @@ -33,6 +33,11 @@ def message_drafts
end
@message.thread.box.tenant.signed_externally_tag!.assign_to_message_object(message_object) if message_object.is_signed

if object_params[:to_be_signed]
@message.tenant.signer_group.signature_requested_from_tag&.assign_to_message_object(message_object)
@message.tenant.signer_group.signature_requested_from_tag&.assign_to_thread(@message.thread)
end

MessageObjectDatum.create(
message_object: message_object,
blob: Base64.decode64(object_params[:content])
Expand Down
1 change: 0 additions & 1 deletion app/controllers/message_drafts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ def submit
if @message.submit
redirect_to message_thread_path(@message.thread), notice: "Správa bola zaradená na odoslanie"
else
# TODO FIX: Tato hlaska sa zobrazuje aj ked je object oznaceny ako to_be_signed, ale nebol este podpisany
redirect_to message_thread_path(@message.thread), alert: @message.not_submittable_errors.join(', ')
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ def submit
message_threads = message_thread_policy_scope.where(id: ids).includes(:messages)
message_threads.transaction do
submission_results = SubmitMessageDraftsAction.run(message_threads)
if submission_results
redirect_back fallback_location: message_threads_path, notice: "Správy vo vláknach boli zaradené na odoslanie", status: 303
else
if submission_results.none?(true)
redirect_back fallback_location: message_threads_path, alert: "Vo vláknach sa našli správy, ktoré neboli podpísané všetkými podpismi", status: 303 and return if any_missing_signature?(message_threads)
redirect_back fallback_location: message_threads_path, alert: "Vo vláknach sa nenašli žiadne správy na odoslanie", status: 303
else
redirect_back fallback_location: message_threads_path, alert: "Správy, ktoré neboli podpísané všetkými podpismi neboli zaradené na odoslanie", status: 303 and return if any_missing_signature?(message_threads)
redirect_back fallback_location: message_threads_path, notice: "Správy vo vláknach boli zaradené na odoslanie", status: 303
end
end
end
Expand Down Expand Up @@ -41,6 +43,10 @@ def destroy
def message_thread_policy_scope
policy_scope(MessageThread)
end

def any_missing_signature?(message_threads)
MessageThreadsTag.where(message_thread: message_threads, tag: Current.tenant.tags.signature_requesting).exists?
end
end
end
end
6 changes: 5 additions & 1 deletion app/jobs/upvs/drafts/load_content_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,16 @@ def load_message_draft_objects(message_draft, objects_path, signed:, to_be_signe
mimetype: Utils.file_mimetype_by_name(entry_name: file_name, is_form: is_form),
object_type: is_form ? "FORM" : "ATTACHMENT",
is_signed: signed,
to_be_signed: to_be_signed,
message: message_draft,
visualizable: is_form ? false : nil,
tags: tags
)

if to_be_signed
message_draft_object.message.tenant.signer_group.signature_requested_from_tag&.assign_to_message_object(message_draft_object)
message_draft_object.message.tenant.signer_group.signature_requested_from_tag&.assign_to_thread(message_draft_object.message.thread)
end

MessageObjectDatum.create(
message_object: message_draft_object,
blob: File.read(File.join(objects_path, file_name))
Expand Down
5 changes: 2 additions & 3 deletions app/models/fs/message_draft.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,12 @@ def self.create_and_validate_with_fs_form(form_files: [], author:, fs_client: Fs
form_object = message.objects.create(
object_type: 'FORM',
name: form_file.original_filename,
mimetype: form_file.content_type,
to_be_signed: fs_form.signature_required
mimetype: form_file.content_type
)
form_object.update(is_signed: form_object.asice?)
message.thread.box.tenant.signed_externally_tag!.assign_to_message_object(form_object) if form_object.is_signed?

if form_object.to_be_signed && !form_object.is_signed?
if fs_form.signature_required && !form_object.is_signed?
message.thread.box.tenant.signer_group.signature_requested_from_tag&.assign_to_message_object(form_object)
message.thread.box.tenant.signer_group.signature_requested_from_tag&.assign_to_thread(message.thread)
end
Expand Down
4 changes: 4 additions & 0 deletions app/models/message.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ def authorized?
metadata["delivery_notification"] && metadata["authorized"] == true
end

def any_objects_with_requested_signature?
MessageObjectsTag.where(message_object: objects, tag: tenant.tags.signature_requesting).exists?
end

# TODO remove UPVS stuff from core domain
def form
::Upvs::Form.find_by(
Expand Down
4 changes: 2 additions & 2 deletions app/models/message_draft.rb
Original file line number Diff line number Diff line change
Expand Up @@ -106,15 +106,15 @@ def created_from_template?
end

def submittable?
form_object.content.present? && objects.to_be_signed.all? { |o| o.is_signed? } && correctly_created? && valid?(:validate_data)
form_object&.content&.present? && correctly_created? && valid?(:validate_data) && !any_objects_with_requested_signature?
end

def not_submittable_errors
return [] if submittable?

errors = []
errors << 'Vyplňte obsah správy' unless form_object.content.present?
errors << 'Pred odoslaním podpíšte všetky dokumenty na podpis' unless objects.to_be_signed.all? { |o| o.is_signed? }
errors << 'Pred odoslaním podpíšte všetky dokumenty na podpis' if any_objects_with_requested_signature?
errors << 'Obsah správy nie je validný' if invalid? || !valid?(:validate_data)
errors << 'Správu bude možné odoslať až po ukončení validácie' if being_validated?

Expand Down
9 changes: 3 additions & 6 deletions app/models/message_object.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
# mimetype :string
# name :string
# object_type :string not null
# to_be_signed :boolean default(FALSE), not null
# uuid :uuid
# visualizable :boolean
# created_at :datetime not null
Expand All @@ -25,8 +24,6 @@ class MessageObject < ApplicationRecord
has_one :archived_object, dependent: :destroy

scope :unsigned, -> { where(is_signed: false) }
scope :to_be_signed, -> { where(to_be_signed: true) }
scope :should_be_signed, -> { where(to_be_signed: true, is_signed: false) }

validates :name, presence: { message: "Name can't be blank" }, on: :validate_data
validate :allowed_mimetype?, on: :validate_data
Expand Down Expand Up @@ -163,11 +160,11 @@ def thread

def remove_object_related_tags_from_thread
tags.each do |tag|
message.thread.unassign_tag(tag) unless other_thread_objects_include_tag?(tag)
thread.unassign_tag(tag) unless other_thread_objects_include_tag?(tag)
end

message.thread.unassign_tag(message.tenant.signed_tag!) unless message.thread.tags.reload.where(type: SignedByTag.to_s).any?
message.thread.unassign_tag(message.tenant.signature_requested_tag!) unless message.thread.tags.reload.where(type: SignatureRequestedFromTag.to_s).any?
thread.unassign_tag(message.tenant.signed_tag!) unless thread.tags.reload.where(type: SignedByTag.to_s).any?
thread.unassign_tag(message.tenant.signature_requested_tag!) unless thread.tags.reload.where(type: SignatureRequestedFromTag.to_s).any?
end

def other_thread_objects_include_tag?(tag)
Expand Down
1 change: 1 addition & 0 deletions app/models/tag.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class Tag < ApplicationRecord
scope :signing_tags, -> { where(type: ["SignedTag", "SignedByTag", "SignatureRequestedTag", "SignatureRequestedFromTag"]) }
scope :signed, -> { where(type: ["SignedTag", "SignedByTag", "SignedExternallyTag"]) }
scope :signed_by, -> { where(type: "SignedByTag") }
scope :signature_requesting, -> { where(type: "SignatureRequestedFromTag") }
scope :signed_internally, -> { where(type: ["SignedTag", "SignedByTag"]) }
scope :archived, -> { where(type: ArchivedTag.to_s) }

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class RemoveToBeSignedAttributeFromMessageObjects < ActiveRecord::Migration[7.1]
def change
remove_column :message_objects, :to_be_signed
end
end
3 changes: 1 addition & 2 deletions db/schema.rb

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion public/openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ paths:
description: Indikátor či je obsah objektu podpísaný
type: boolean
to_be_signed:
description: Indikátor či obsah objektu má byť podpísaný
description: Indikátor či obsah objektu má byť podpísaný. V prípade hodnoty true je vyžiadaný podpis na danom objekte
type: boolean
mimetype:
description: Typ internetového média v súlade s typom a obsahom objektu
Expand Down
8 changes: 8 additions & 0 deletions test/fixtures/message_object_data.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,18 @@ two:
message_object: ssd_main_general_two_form
blob: MyText

main_draft:
message_object: ssd_main_draft_form
blob: <GeneralAgenda xmlns="http://schemas.gov.sk/form/App.GeneralAgenda/1.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><subject>predmet</subject><text>text</text></GeneralAgenda>

draft_two:
message_object: ssd_main_general_draft_two_form
blob: <GeneralAgenda xmlns="http://schemas.gov.sk/form/App.GeneralAgenda/1.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><subject>predmet</subject><text>text</text></GeneralAgenda>

draft_three:
message_object: ssd_main_draft_to_be_signed2_draft_form
blob: <GeneralAgenda xmlns="http://schemas.gov.sk/form/App.GeneralAgenda/1.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><subject>predmet</subject><text>text</text></GeneralAgenda>

empty_draft:
message_object: ssd_main_empty_draft_form
blob: <GeneralAgenda xmlns="http://schemas.gov.sk/form/App.GeneralAgenda/1.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><subject></subject><text></text></GeneralAgenda>
Expand Down
8 changes: 7 additions & 1 deletion test/fixtures/message_objects.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,12 @@ ssd_main_fs_one_form:
mimetype: application/x-eform-xml
object_type: FORM

ssd_main_draft_form:
message: ssd_main_draft
name: MyString
mimetype: application/x-eform-xml
object_type: FORM

ssd_main_draft_to_be_signed_draft_one_form:
uuid: 6a0f716a-c284-4680-ad7e-ed2bde769dd2
message: ssd_main_draft_to_be_signed_draft_one
Expand Down Expand Up @@ -80,7 +86,7 @@ ssd_main_draft_to_be_signed_draft_two_form:
ssd_main_draft_to_be_signed2_draft_form:
message: ssd_main_draft_to_be_signed2_draft
name: MyString
mimetype: MyString
mimetype: application/x-eform-xml
object_type: FORM

ssd_main_draft_to_be_signed3_draft_one_form:
Expand Down
9 changes: 8 additions & 1 deletion test/fixtures/messages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ ssd_main_draft_to_be_signed_draft_two:
author: basic

ssd_main_draft_to_be_signed2_draft:
type: MessageDraft
type: Upvs::MessageDraft
uuid: <%= SecureRandom.uuid %>
title: MyStringDraft3
html_visualization: MyString
Expand All @@ -226,6 +226,13 @@ ssd_main_draft_to_be_signed2_draft:
replyable: false
metadata:
status: created
sktalk_class: EGOV_APPLICATION
posp_id: App.GeneralAgenda
posp_version: 1.9
message_type: App.GeneralAgenda
correlation_id: <%= SecureRandom.uuid %>
recipient_uri:
ico://sk/12345678
author: basic

ssd_main_draft_to_be_signed3_draft:
Expand Down
36 changes: 36 additions & 0 deletions test/integration/upvs_message_drafts_api_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,42 @@ class UpvsMessageDraftsApiTest < ActionDispatch::IntegrationTest
assert_not_equal Message.count, @before_request_messages_count
end

test 'SignatureRestedTag is assigned from SignerGroup if object marked to_be_signed' do
message_params = {
type: 'Upvs::MessageDraft',
title: 'Všeobecná agenda',
uuid: SecureRandom.uuid,
metadata: {
posp_id: 'App.GeneralAgenda',
posp_version: '1.9',
message_type: 'App.GeneralAgenda',
correlation_id: SecureRandom.uuid,
sender_uri: 'SSDMainURI',
recipient_uri: 'ico://sk/12345678',
},
objects: [
{
name: 'Form.xml',
is_signed: false,
to_be_signed: true,
mimetype: 'application/x-eform-xml',
object_type: 'FORM',
content: Base64.encode64('<?xml version="1.0" encoding="utf-8"?>
<GeneralAgenda xmlns="http://schemas.gov.sk/form/App.GeneralAgenda/1.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<subject>Všeobecný predmet</subject>
<text>Všeobecný text</text>
</GeneralAgenda>')
}
]
}

post '/api/messages/message_drafts', params: message_params.merge({ token: generate_api_token(sub: @tenant.id, key_pair: @key_pair)} ), as: :json

assert_response :created
assert @box.messages.last.objects.first.tags.include?(@tenant.signer_group.signature_requested_from_tag)
assert @box.messages.last.thread.tags.include?(@tenant.signature_requested_tag!)
end

test 'can upload valid message with tags if they exist' do
message_params = {
type: 'Upvs::MessageDraft',
Expand Down
9 changes: 9 additions & 0 deletions test/models/message_object_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,15 @@ class MessageObjectTest < ActiveSupport::TestCase
assert_not object.message.thread.tags.include?(tenant.signed_tag!)
end

test "before_destroy callback deletes SignatureRequested Tag from message thread (if no more objects with SignatureRequestedFromTag present)" do
message_object = message_objects(:ssd_main_draft_form)
message_thread = message_object.message.thread

message_object.destroy

assert_equal false, message_thread.tags.reload.include?(message_thread.tenant.signature_requested_tag!)
end

test "before_destroy callback keeps object related tags for message thread (if another objects with the tag present in the message)" do
tenant = tenants(:ssd)
signer = users(:basic_two)
Expand Down
15 changes: 15 additions & 0 deletions test/system/message_drafts_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,19 @@ class MessageDraftsTest < ApplicationSystemTestCase
refute_selector(thread_in_listing_selector(thread_general))
refute_selector(thread_in_listing_selector(thread_issue))
end

test "message is not submitted and flash message is shown when user tries to send message without requested signatures present" do
message_thread = message_threads(:ssd_main_draft_to_be_signed2)
message_draft = messages(:ssd_main_draft_to_be_signed2_draft)

visit message_thread_path(message_thread)

within("#upvs_message_draft_#{message_draft.id}") do
assert_button "Odoslať"

click_button "Odoslať"
end

assert_text "Pred odoslaním podpíšte všetky dokumenty na podpis"
end
end

0 comments on commit 5562e60

Please sign in to comment.