Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
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: 5 additions & 2 deletions froide/foirequest/models/attachment.py
Original file line number Diff line number Diff line change
Expand Up @@ -388,12 +388,15 @@ def remove_file_and_delete(self):
self.file.delete(save=False)
self.delete()

def can_convert_to_pdf(self):
def is_filetype_convertable_to_pdf(self):
from filingcabinet.pdf_utils import can_convert_to_pdf

ft = self.filetype.lower()
name = self.name.lower()
return self.converted_id is None and can_convert_to_pdf(ft, name=name)
return can_convert_to_pdf(ft, name=name)

def can_convert_to_pdf(self):
return self.converted_id is None and self.is_filetype_convertable_to_pdf()

def create_document(self, title=None):
if self.document is not None:
Expand Down
9 changes: 7 additions & 2 deletions froide/foirequest/models/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,12 @@ class MessageKind(models.TextChoices):
MessageKind.IMPORT: "cloud-download",
}

MANUAL_MESSAGE_KINDS = {MessageKind.POST, MessageKind.PHONE, MessageKind.VISIT}
MANUAL_MESSAGE_KINDS = {
MessageKind.POST,
MessageKind.PHONE,
MessageKind.VISIT,
}

MESSAGE_ID_PREFIX = "foimsg."


Expand Down Expand Up @@ -643,7 +648,7 @@ def get_original_email_from_imap(self):
return data

def fails_authenticity(self):
if not self.is_response or not self.is_email:
if not self.is_response or not self.is_email or not self.email_headers:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

return
checks = self.email_headers.get("authenticity")
if not checks:
Expand Down
10 changes: 10 additions & 0 deletions froide/foirequest/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ class FoiMessageSerializer(serializers.HyperlinkedModelSerializer):
read_only=True,
)
status_name = serializers.CharField(source="get_status_display", read_only=True)
fails_authenticity = serializers.BooleanField(default=True, read_only=True)
is_escalation_message = serializers.BooleanField(default=False, read_only=True)

class Meta:
model = FoiMessage
Expand All @@ -289,6 +291,7 @@ class Meta:
"is_draft",
"kind",
"is_escalation",
"is_escalation_message",
"content_hidden",
"sender_public_body",
"recipient_public_body",
Expand All @@ -305,14 +308,17 @@ class Meta:
"sender",
"status_name",
"last_modified_at",
"fails_authenticity",
]
read_only_fields = [
"sent",
"is_escalation",
"is_escalation_message",
"content_hidden",
"is_draft",
"not_publishable",
"last_modified_at",
"fails_authenticity",
]

def _is_authenticated_read(self, obj):
Expand Down Expand Up @@ -454,6 +460,9 @@ class FoiAttachmentSerializer(serializers.HyperlinkedModelSerializer):
resource_uri = serializers.HyperlinkedIdentityField(
view_name="api:attachment-detail", lookup_field="pk"
)
is_filetype_convertable_to_pdf = serializers.BooleanField(
default=False, read_only=True
)
converted = serializers.HyperlinkedRelatedField(
view_name="api:attachment-detail",
lookup_field="pk",
Expand Down Expand Up @@ -485,6 +494,7 @@ class Meta:
"file_url",
"pending",
"is_converted",
"is_filetype_convertable_to_pdf",
"converted",
"approved",
"can_approve",
Expand Down
2 changes: 1 addition & 1 deletion froide/foirequest/signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ def notify_user_message_received(sender, message=None, **kwargs):
"user": sender.user,
"publicbody": message.sender_public_body,
"action_url": sender.user.get_autologin_url(
message.get_absolute_short_url()
short_request_url("foirequest-edit_message_flow_email", sender, message)
),
},
priority=False,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,14 +207,16 @@
</div>
{% endif %}
{% endif %}
{# Redact button #}
{% if object|can_write_foirequest:request or object|can_moderate_pii_foirequest:request %}
{% render_message_redact_button message %}
{% endif %}
{# Edit button #}
{% if object|can_write_foirequest:request %}
{% render_message_edit_button message %}
{% endif %}
{% endif %}
<!-- Problem button-->
{# Problem button #}
{% render_problem_button message %}
{% if object|can_moderate_foirequest:request and message.can_resend_bounce %}
{% include "foirequest/body/message/toolbar/resend.html" %}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
{% extends "fullscreen_app.html" %}
{% load i18n %}
{% load static %}
{% load block_helper %}
{% load frontendbuild %}
{% load form_helper %}
{% load content_helper %}
{% load foirequest_tags %}
{% load problemreport_tags %}
{% block title %}
{% blocktrans with title=object.title %}Edit e-mail response for “{{ title }}”{% endblocktrans %}
{% endblock title %}
{% block navbar %}
{% include "header_reduced.html" %}
{% endblock navbar %}
{% block body %}
<div class="bg-body-tertiary editmessageflow-breadcrumbs">
{% translate "Edit e-mail response" as breadcrumb_label %}
{% include "foirequest/header/breadcrumb.html" with last_item=breadcrumb_label %}
</div>
{# the form never submits, but is useful for checkValidity #}
<form name="editmessageflow" class="d-flex flex-col flex-grow-1">
{% csrf_token %}
{# mw-100 crucial for pdf-redaction's dynamic maxWidth calculations #}
<edit-message-flow class="d-flex flex-column flex-grow-1 mw-100" :config="{{ config_json }}" :schemas="{{ schemas_json }}" :foirequest="{{ foirequest_json }}" :date_max="{{ date_max }}" :date_min="{{ date_min }}" :user_is_staff="{{ user_is_staff }}" :message="{{ message_json }}" :message_timestamp_relative="{{ message.timestamp|relativetime }}" :message_timestamp_local="{{ message.timestamp }}" :currency="{{ froide.currency }}">
<template data-slot="message_sender">
{% include "foirequest/body/message/sender.html" %}
</template>
<template data-slot="redaction_explanation">
{% include "foirequest/snippets/redaction_explanation.html" %}
</template>
<template data-slot="message_content_hidden">
{% blocktrans %}This message may contain information that you may wish to not publish until after the whole request finished. The following message is therefore currently only visible to you.{% endblocktrans %}
</template>
<template data-slot="redactbutton">
{% if object|can_write_foirequest:request or object|can_moderate_pii_foirequest:request %}
{% render_message_redact_button message is_edit_message_flow_email=True partial='button' %}
{% endif %}
</template>
<template data-slot="problembutton">
{% render_problem_button message is_edit_message_flow_email=True partial='button' %}
</template>
{# avoid whitespace, since this will be pre-wrap. spaceless didn't work... #}
<template data-slot="message_subject_redacted">{% redact_subject message request %}</template>
<template data-slot="message_content_redacted">{% redact_message message request %}</template>
<template data-slot="email_request_link">
<p>
{% trans "Read the full message thread on the request page:" %}
<a href="{{ message.get_absolute_url }}">{{ object.title }}</a>
</p>
</template>
</edit-message-flow>
</form>
{% if object|can_write_foirequest:request or object|can_moderate_pii_foirequest:request %}
{% render_message_redact_button message is_edit_message_flow_email=True partial='modal' %}
{% endif %}
{% render_problem_button message is_edit_message_flow_email=True partial='modal' %}
{% endblock body %}
{% block scripts %}
{{ block.super }}
{% addfrontendbuild "request.js" %}
{% addfrontendbuild "publicbody.js" %}
{% addfrontendbuild "editmessageflow.js" %}
{% addfrontendbuild "messageredaction.js" %}
{% addfrontendbuild "fileuploader.js" %}
{% endblock scripts %}
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,34 @@
{% load block_helper %}
{% load frontendbuild %}
{% load form_helper %}
{% load content_helper %}
{% load foirequest_tags %}
{% block title %}
{% blocktrans with title=object.title %}Upload postal mail for “{{ title }}”{% endblocktrans %}
{% endblock title %}
{% block navbar %}
{% include "header_reduced.html" %}
{% endblock navbar %}
{% block body %}
<div class="bg-body-tertiary postupload-breadcrumbs">
<div class="bg-body-tertiary editmessageflow-breadcrumbs">
{% translate "Upload postal mail" as breadcrumb_label %}
{% include "foirequest/header/breadcrumb.html" with last_item=breadcrumb_label %}
</div>
{# the form never submits, but is useful for checkValidity #}
<form name="postupload" class="d-flex flex-col flex-grow-1">
<form name="editmessageflow" class="d-flex flex-col flex-grow-1">
{% csrf_token %}
{# mw-100 crucial for pdf-redaction's dynamic maxWidth calculations #}
<post-upload class="d-flex flex-column flex-grow-1 mw-100" :config="{{ config_json }}" :schemas="{{ schemas_json }}" :foirequest="{{ foirequest_json }}" :date_max="{{ date_max }}" :date_min="{{ date_min }}" :user_is_staff="{{ user_is_staff }}" :message="{{ message_json }}" :currency="{{ froide.currency }}">
<edit-message-flow class="d-flex flex-column flex-grow-1 mw-100" :config="{{ config_json }}" :schemas="{{ schemas_json }}" :foirequest="{{ foirequest_json }}" :date_max="{{ date_max }}" :date_min="{{ date_min }}" :user_is_staff="{{ user_is_staff }}" :message="{{ message_json }}" :message_timestamp_relative="{{ message.timestamp|relativetime }}" :message_timestamp_local="{{ message.timestamp }}" :currency="{{ froide.currency }}">
<template data-slot="redaction_explanation">
{% include "foirequest/snippets/redaction_explanation.html" %}
</template>
</post-upload>
</edit-message-flow>
</form>
{% endblock body %}
{% block scripts %}
{{ block.super }}
{% addfrontendbuild "request.js" %}
{% addfrontendbuild "publicbody.js" %}
{% addfrontendbuild "postupload.js" %}
{% addfrontendbuild "editmessageflow.js" %}
{% addfrontendbuild "fileuploader.js" %}
{% endblock scripts %}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{% load i18n %}
{% load markup %}
{% load form_helper %}
{% if show_button %}
{% if is_redactable and render_button %}
<div class="btn-group btn-group-sm mx-sm-1 mb-1">
<button type="button"
title="{% trans 'Redact message text' %}"
Expand All @@ -12,6 +12,8 @@
{% trans "Redact" %}
</button>
</div>
{% endif %}
{% if is_redactable and render_modal %}
<div class="modal"
data-teleport="body"
tabindex="-1"
Expand All @@ -37,6 +39,7 @@ <h5 class="modal-title">{% trans "Redact / unredact message" %}</h5>
class="disable-submit"
action="{% url 'foirequest-redact_message' slug=foirequest.slug message_id=message.pk %}">
{% csrf_token %}
{% if is_edit_message_flow_email %}<input type="hidden" name="edit_message_flow_email" value="1" />{% endif %}
<p>
{% translate "If there's important information below the message like inline replies, use the following button to unredact that part. Afterwards, personally identifiable information may need to be redacted again." %}
</p>
Expand All @@ -51,6 +54,7 @@ <h5 class="modal-title">{% trans "Redact / unredact message" %}</h5>
<form method="post"
action="{% url 'foirequest-redact_message' slug=foirequest.slug message_id=message.pk %}">
{% csrf_token %}
{% if is_edit_message_flow_email %}<input type="hidden" name="edit_message_flow_email" value="1" />{% endif %}
<message-redaction :config="{{ js_config }}" message-url="{% url 'api:message-detail' pk=message.pk %}"></message-redaction>
<p class="text-end">
<button type="submit" class="btn btn-dark">{% trans "Change message redaction" %}</button>
Expand Down
9 changes: 7 additions & 2 deletions froide/foirequest/templatetags/foirequest_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -451,15 +451,20 @@ def render_message_edit_button(message):


@register.inclusion_tag("foirequest/snippets/message_redact.html")
def render_message_redact_button(message):
def render_message_redact_button(
message, is_edit_message_flow_email=False, partial=None
):
blocked_patterns = [
pat.pattern
for pat in get_minimum_redaction_replacements(message.request).keys()
]
return {
"foirequest": message.request,
"message": message,
"show_button": bool(message.plaintext or message.subject),
"is_redactable": bool(message.plaintext or message.subject),
"is_edit_message_flow_email": is_edit_message_flow_email,
"render_button": partial is None or partial == "button",
"render_modal": partial is None or partial == "modal",
"js_config": json.dumps(
{
"i18n": {
Expand Down
13 changes: 10 additions & 3 deletions froide/foirequest/urls/request_urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
download_message_pdf,
download_original_email,
edit_message,
edit_postal_message,
edit_message_flow,
escalation_message,
extend_deadline,
make_public,
Expand Down Expand Up @@ -114,8 +114,15 @@
),
path(
pgettext_lazy("url part", "<slug:slug>/<int:message_id>/edit-postal-message/"),
edit_postal_message,
name="foirequest-edit_postal_message",
edit_message_flow,
{"is_email": False},
name="foirequest-edit_message_flow_postal",
),
path(
pgettext_lazy("url part", "<slug:slug>/<int:message_id>/edit-email-response/"),
edit_message_flow,
{"is_email": True},
name="foirequest-edit_message_flow_email",
),
path(
"<slug:slug>/apply-moderation/",
Expand Down
4 changes: 2 additions & 2 deletions froide/foirequest/views/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
download_message_pdf,
download_original_email,
edit_message,
edit_postal_message,
edit_message_flow,
escalation_message,
message_shortlink,
redact_message,
Expand Down Expand Up @@ -108,7 +108,7 @@
"resend_message",
"upload_attachments",
"edit_message",
"edit_postal_message",
"edit_message_flow",
"redact_message",
"download_message_pdf",
"download_message_letter_pdf",
Expand Down
Loading