Merge pull request #3659 from modoboa/fix/download_pdfcredentials

Make sure download link for PDF credentials actually work.
This commit is contained in:
Antoine Nguyen
2025-08-06 13:13:43 +02:00
committed by GitHub
5 changed files with 62 additions and 9 deletions
+3
View File
@@ -17,6 +17,9 @@ export default {
getRandomPassword() {
return repository.get(`${resource}/random_password/`)
},
getCredentials(accountId) {
return repository.get(`credentials/${accountId}/`, { responseType: 'blob' })
},
validate(data) {
return repository.post(`${resource}/validate/`, data)
},
@@ -362,9 +362,9 @@ function getMenuItems(item) {
result.push({
label: element.label,
icon: element.icon,
onClick: () => {
if (element.type === 'download') {
//TODO : downloadFile(element)
onClick: (account) => {
if (element.name === 'get_credentials') {
downloadCredentials(account)
}
fetchIdentities()
},
@@ -438,6 +438,16 @@ async function deleteAccount(account) {
}
}
async function downloadCredentials(account) {
const resp = await accountsApi.getCredentials(account.pk)
const blob = new Blob([resp.data], { type: resp.headers['Content-Type'] })
const link = document.createElement('a')
link.href = URL.createObjectURL(blob)
link.download = `credentials_${account.pk}.pdf`
link.click()
URL.revokeObjectURL(link.href)
}
function editAlias() {}
function deleteIdentities() {}
+17 -5
View File
@@ -38,12 +38,16 @@ class PDFCredentialsSettingsSerializer(serializers.Serializer):
required=False, allow_blank=True, allow_null=True
)
include_connection_settings = serializers.BooleanField(default=False)
smtp_server_address = serializers.CharField()
smtp_server_address = serializers.CharField(
required=False, allow_blank=True, allow_null=True
)
smtp_server_port = serializers.IntegerField(default=587)
smtp_connection_security = serializers.ChoiceField(
choices=CONNECTION_SECURITY_MODES, default="starttls"
)
imap_server_address = serializers.CharField()
imap_server_address = serializers.CharField(
required=False, allow_blank=True, allow_null=True
)
imap_server_port = serializers.IntegerField(default=143)
imap_connection_security = serializers.ChoiceField(
choices=CONNECTION_SECURITY_MODES, default="starttls"
@@ -72,13 +76,21 @@ class PDFCredentialsSettingsSerializer(serializers.Serializer):
enabled_pdfcredentials is None
and param_tools.get_global_parameter("enabled_pdfcredentials")
)
errors = {}
if condition:
storage_dir = data.get("storage_dir", None)
if storage_dir is not None:
if not os.path.isdir(storage_dir):
raise serializers.ValidationError(_("Directory not found."))
if not os.access(storage_dir, os.W_OK):
raise serializers.ValidationError(_("Directory is not writable"))
errors["storage_dir"] = _("Directory not found.")
elif not os.access(storage_dir, os.W_OK):
errors["storage_dir"] = _("Directory is not writable")
include_connection_settings = data.get("include_connection_settings")
if include_connection_settings:
for field in ["smtp_server_address", "imap_server_address"]:
if not data.get(field):
errors[field] = _("This field is required.")
if errors:
raise serializers.ValidationError(errors)
return data
+28
View File
@@ -190,3 +190,31 @@ class PDFCredentialViewTestCase(ModoAPITestCase):
data["enabled_pdfcredentials"] = False
resp = self.client.put(url, data, format="json")
self.assertEqual(resp.status_code, 200)
def test_optional_settings(self):
url = reverse("v2:parameter-global-detail", args=["pdfcredentials"])
path = f"{self.workdir}/credentials"
os.makedirs(path)
data = {
"enabled_pdfcredentials": True,
"storage_dir": path,
"webpanel_url": "http://localhost",
}
resp = self.client.put(url, data, format="json")
self.assertEqual(resp.status_code, 200)
data["include_connection_settings"] = True
resp = self.client.put(url, data, format="json")
self.assertEqual(resp.status_code, 400)
errors = resp.json()
self.assertEqual(errors["smtp_server_address"][0], "This field is required.")
self.assertEqual(errors["imap_server_address"][0], "This field is required.")
data.update(
{
"smtp_server_address": "mail.localhost",
"imap_server_address": "mail.localhost",
}
)
resp = self.client.put(url, data, format="json")
self.assertEqual(resp.status_code, 200)
+1 -1
View File
@@ -121,7 +121,7 @@ PDF_CREDENTIALS_PARAMETERS_STRUCT = collections.OrderedDict(
"smtp_server_address",
{
"label": _("SMTP server address"),
"display": "include_connection_settings=True",
"display": "include_connection_settings=true",
"help_text": _(
"Address of the SMTP server (hostname or IP)"
),