Skip to content

Commit d567660

Browse files
committed
Fixed CodeRabbit issues
1 parent 3126c1a commit d567660

File tree

3 files changed

+40
-17
lines changed

3 files changed

+40
-17
lines changed

src/imio/esign/browser/settings.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
from plone import api
55
from plone.app.registry.browser.controlpanel import ControlPanelFormWrapper
66
from plone.app.registry.browser.controlpanel import RegistryEditForm
7-
from plone.registry.interfaces import IRecordModifiedEvent
87
from plone.z3cform import layout
8+
from string import Formatter
99
from zope import schema
1010
from zope.interface import Interface
1111
from zope.interface import Invalid
@@ -38,6 +38,15 @@ def validate_vat_number(va_nb):
3838

3939
return True
4040

41+
def validate_signing_users_email_content(value):
42+
"""Allow only known placeholders in the email template."""
43+
allowed = {"fullname", "firstname", "lastname", "email", "userid"}
44+
for _ignored1, field, _ignored2, _ignored3 in Formatter().parse(value or ""):
45+
if field and field not in allowed:
46+
raise Invalid(
47+
_("Unknown placeholder: ${field}", mapping={"field": field})
48+
)
49+
return True
4150

4251
class IImioEsignSettings(Interface):
4352

@@ -85,6 +94,7 @@ class IImioEsignSettings(Interface):
8594
"Use {fullname}, {firstname}, {lastname}, {email}, {userid} as placeholders."
8695
),
8796
required=False,
97+
constraint=validate_signing_users_email_content,
8898
default=u"""Hello {fullname},
8999
90100
You have been invited to Parapheo, the signing platform of iMio.

src/imio/esign/browser/templates/signing_users.pt

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@
177177
Deselect All
178178
</button>
179179
<span class="stats">
180-
<strong i18n:translate="">Selected:</strong>
180+
<strong i18n:translate="">Selected:</strong>
181181
<span id="selected-count">0</span>
182182
/ <span tal:content="python:len(all_users)">0</span>
183183
</span>
@@ -195,7 +195,12 @@
195195
</div>
196196
</div>
197197

198-
<form id="users-form" method="post">
198+
<form id="users-form" method="post" tal:attributes="action string:${context/absolute_url}/@@signing-users-csv">
199+
<!-- Hidden inputs for form submission -->
200+
<input type="hidden" name="_authenticator" tal:attributes="value context/@@authenticator/token" />
201+
<input type="hidden" name="action" id="form-action" value="" />
202+
<input type="hidden" name="selected_users" id="selected-users" value="" />
203+
199204
<table class="listing" id="users-table" style="width: 100%;">
200205
<thead>
201206
<tr>
@@ -217,7 +222,7 @@
217222
style python:'background-color: #ffe6e6' if user.get('has_duplicate_email') else ''">
218223
<td>
219224
<input type="checkbox"
220-
name="selected_users"
225+
name="user_checkbox"
221226
class="user-checkbox"
222227
tal:attributes="value user/userid;
223228
checked python:'checked' if user['checked'] else None" />
@@ -286,7 +291,7 @@
286291
function updateSelectedCount() {
287292
var count = document.querySelectorAll('.user-checkbox:checked').length;
288293
selectedCount.textContent = count;
289-
294+
290295
// Update select all checkbox state
291296
var allChecked = Array.from(checkboxes).every(function(cb) { return cb.checked; });
292297
var someChecked = Array.from(checkboxes).some(function(cb) { return cb.checked; });
@@ -311,11 +316,11 @@
311316
return;
312317
}
313318
314-
var url = window.location.href.split('?')[0];
315-
var params = 'action=' + action + '&selected_users=' + encodeURIComponent(JSON.stringify(selected));
316-
317319
if (action === 'download_csv') {
318-
window.location.href = url + '?' + params;
320+
// For CSV download, set the action and selected users, then submit
321+
document.getElementById('form-action').value = action;
322+
document.getElementById('selected-users').value = JSON.stringify(selected);
323+
form.submit();
319324
} else if (action === 'send_emails') {
320325
// Show confirmation modal
321326
document.getElementById('email-count').textContent = selected.length;
@@ -376,9 +381,11 @@
376381
377382
confirmEmailBtn.addEventListener('click', function() {
378383
var selected = getSelectedUserIds();
379-
var url = window.location.href.split('?')[0];
380-
var params = 'action=send_emails&selected_users=' + encodeURIComponent(JSON.stringify(selected));
381-
window.location.href = url + '?' + params;
384+
// Set the action and selected users in hidden inputs
385+
document.getElementById('form-action').value = 'send_emails';
386+
document.getElementById('selected-users').value = JSON.stringify(selected);
387+
// Submit the form via POST
388+
form.submit();
382389
});
383390
384391
// Close modal on outside click

src/imio/esign/browser/views.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -476,15 +476,21 @@ def get_users_data(self):
476476
return all_users_data, duplicates
477477

478478
def _get_selected_userids(self):
479-
"""Get list of selected user IDs from request."""
479+
"""Get list of selected user IDs from request.
480+
481+
Expects a JSON-formatted list in 'selected_users' parameter.
482+
Returns an empty list if the input is not valid JSON.
483+
"""
480484
selected = self.request.get("selected_users", "")
485+
481486
if not selected:
482487
return []
483488

484-
# Handle both JSON array and form data
485-
if selected.startswith("["):
489+
# Parse JSON array
490+
try:
486491
return json.loads(selected)
487-
return [uid.strip() for uid in selected.split(",") if uid.strip()]
492+
except (json.JSONDecodeError, ValueError, TypeError):
493+
return []
488494

489495
def _download_csv(self):
490496
"""Generate and download CSV file with selected users."""
@@ -540,7 +546,7 @@ def _send_emails(self):
540546
)
541547
return self.request.RESPONSE.redirect(self.context.absolute_url() + "/@@signing-users-csv")
542548

543-
all_users_data, duplicates = self.get_users_data()
549+
all_users_data, _duplicates = self.get_users_data()
544550
selected_users = [u for u in all_users_data if u["userid"] in selected_userids]
545551

546552
portal_email = api.portal.get().getProperty("email_from_address")

0 commit comments

Comments
 (0)