Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GO-49 Do not submit message unless requested signatures present #484

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)
jsuchal marked this conversation as resolved.
Show resolved Hide resolved
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
Loading