Coverage Report

Created: 2025-12-31 10:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/svx/source/dialog/signaturelinehelper.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 */
9
10
#include <svx/signaturelinehelper.hxx>
11
12
#include <com/sun/star/drawing/XShape.hpp>
13
#include <com/sun/star/graphic/GraphicProvider.hpp>
14
#include <com/sun/star/security/DocumentDigitalSignatures.hpp>
15
16
#include <comphelper/processfactory.hxx>
17
#include <comphelper/propertyvalue.hxx>
18
#include <comphelper/sequenceashashmap.hxx>
19
#include <comphelper/storagehelper.hxx>
20
#include <comphelper/xmlsechelper.hxx>
21
#include <config_folders.h>
22
#include <rtl/bootstrap.hxx>
23
#include <sal/log.hxx>
24
#include <sfx2/docfile.hxx>
25
#include <sfx2/docfilt.hxx>
26
#include <sfx2/objsh.hxx>
27
#include <svx/dialmgr.hxx>
28
#include <svx/strings.hrc>
29
#include <svx/svdmark.hxx>
30
#include <svx/svdview.hxx>
31
#include <tools/stream.hxx>
32
#include <unotools/localedatawrapper.hxx>
33
#include <unotools/streamwrap.hxx>
34
#include <unotools/syslocale.hxx>
35
#include <vcl/weld/weld.hxx>
36
#include <sfx2/digitalsignatures.hxx>
37
#include <sfx2/viewsh.hxx>
38
39
using namespace com::sun::star;
40
41
namespace svx::SignatureLineHelper
42
{
43
OUString getSignatureImage(const OUString& rType)
44
0
{
45
0
    OUString aType = rType;
46
0
    if (aType.isEmpty())
47
0
    {
48
0
        aType = "signature-line.svg";
49
0
    }
50
0
    OUString aPath("$BRAND_BASE_DIR/" LIBO_SHARE_FOLDER "/filter/" + aType);
51
0
    rtl::Bootstrap::expandMacros(aPath);
52
0
    SvFileStream aStream(aPath, StreamMode::READ);
53
0
    if (aStream.GetError() != ERRCODE_NONE)
54
0
    {
55
0
        SAL_WARN("cui.dialogs", "failed to open " << aType);
56
0
    }
57
58
0
    OString const svg = read_uInt8s_ToOString(aStream, aStream.remainingSize());
59
0
    return OUString::fromUtf8(svg);
60
0
}
61
62
uno::Reference<security::XCertificate>
63
getSignatureCertificate(SfxObjectShell* pShell, SfxViewShell* pViewShell, weld::Window* pParent)
64
0
{
65
0
    if (!pShell)
66
0
    {
67
0
        return {};
68
0
    }
69
70
0
    if (!pParent)
71
0
    {
72
0
        return {};
73
0
    }
74
75
0
    uno::Reference<security::XDocumentDigitalSignatures> xSigner;
76
0
    if (pShell->GetMedium()->GetFilter()->IsAlienFormat())
77
0
    {
78
0
        xSigner = security::DocumentDigitalSignatures::createDefault(
79
0
            comphelper::getProcessComponentContext());
80
0
    }
81
0
    else
82
0
    {
83
0
        OUString const aODFVersion(
84
0
            comphelper::OStorageHelper::GetODFVersionFromStorage(pShell->GetStorage()));
85
0
        xSigner = security::DocumentDigitalSignatures::createWithVersion(
86
0
            comphelper::getProcessComponentContext(), aODFVersion);
87
0
    }
88
0
    xSigner->setParentWindow(pParent->GetXWindow());
89
0
    OUString aDescription;
90
0
    security::CertificateKind certificateKind = security::CertificateKind_NONE;
91
    // When signing ooxml, we only want X.509 certificates
92
0
    if (pShell->GetMedium()->GetFilter()->IsAlienFormat())
93
0
    {
94
0
        certificateKind = security::CertificateKind_X509;
95
0
    }
96
0
    auto xModelSigner = dynamic_cast<sfx2::DigitalSignatures*>(xSigner.get());
97
0
    assert(xModelSigner);
98
0
    uno::Reference<security::XCertificate> xSignCertificate
99
0
        = xModelSigner->SelectSigningCertificateWithType(pViewShell, certificateKind, aDescription);
100
0
    return xSignCertificate;
101
0
}
102
103
OUString getSignerName(const svl::crypto::CertificateOrName& rCertificateOrName)
104
0
{
105
0
    if (rCertificateOrName.m_xCertificate.is())
106
0
    {
107
0
        return comphelper::xmlsec::GetContentPart(
108
0
            rCertificateOrName.m_xCertificate->getSubjectName(),
109
0
            rCertificateOrName.m_xCertificate->getCertificateKind());
110
0
    }
111
112
0
    return rCertificateOrName.m_aName;
113
0
}
114
115
OUString getLocalizedDate()
116
0
{
117
0
    const SvtSysLocale aSysLocale;
118
0
    const LocaleDataWrapper& rLocaleData = aSysLocale.GetLocaleData();
119
0
    Date aDateTime(Date::SYSTEM);
120
0
    return rLocaleData.getDate(aDateTime);
121
0
}
122
123
uno::Reference<graphic::XGraphic> importSVG(std::u16string_view rSVG)
124
0
{
125
0
    SvMemoryStream aSvgStream(4096, 4096);
126
0
    aSvgStream.WriteOString(OUStringToOString(rSVG, RTL_TEXTENCODING_UTF8));
127
0
    uno::Reference<io::XInputStream> xInputStream(new utl::OSeekableInputStreamWrapper(aSvgStream));
128
0
    const uno::Reference<uno::XComponentContext>& xContext(
129
0
        comphelper::getProcessComponentContext());
130
0
    uno::Reference<graphic::XGraphicProvider> xProvider
131
0
        = graphic::GraphicProvider::create(xContext);
132
133
0
    uno::Sequence<beans::PropertyValue> aMediaProperties{ comphelper::makePropertyValue(
134
0
        u"InputStream"_ustr, xInputStream) };
135
0
    uno::Reference<graphic::XGraphic> xGraphic(xProvider->queryGraphic(aMediaProperties));
136
0
    return xGraphic;
137
0
}
138
139
void setShapeCertificate(SfxViewShell* pViewShell,
140
                         const svl::crypto::CertificateOrName& rCertificateOrName)
141
0
{
142
0
    const SdrView* pView = pViewShell->GetDrawView();
143
0
    const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
144
0
    if (rMarkList.GetMarkCount() < 1)
145
0
    {
146
0
        return;
147
0
    }
148
149
0
    const SdrMark* pMark = rMarkList.GetMark(0);
150
0
    SdrObject* pSignatureLine = pMark->GetMarkedSdrObj();
151
0
    if (!pSignatureLine)
152
0
    {
153
0
        return;
154
0
    }
155
156
    // Remember the selected certificate.
157
0
    uno::Reference<drawing::XShape> xShape = pSignatureLine->getUnoShape();
158
0
    uno::Reference<beans::XPropertySet> xShapeProps(xShape, uno::UNO_QUERY);
159
0
    pViewShell->SetSignPDFCertificate(rCertificateOrName);
160
161
    // Read svg and replace placeholder texts.
162
0
    OUString aSvgImage(
163
0
        svx::SignatureLineHelper::getSignatureImage(u"signature-line-draw.svg"_ustr));
164
0
    aSvgImage = aSvgImage.replaceAll("[SIGNED_BY]", SvxResId(RID_SVXSTR_SIGNATURELINE_DSIGNED_BY));
165
0
    OUString aSignerName = svx::SignatureLineHelper::getSignerName(rCertificateOrName);
166
0
    aSvgImage = aSvgImage.replaceAll("[SIGNER_NAME]", aSignerName);
167
0
    OUString aDate = svx::SignatureLineHelper::getLocalizedDate();
168
0
    aDate = SvxResId(RID_SVXSTR_SIGNATURELINE_DATE).replaceFirst("%1", aDate);
169
0
    aSvgImage = aSvgImage.replaceAll("[DATE]", aDate);
170
171
0
    uno::Reference<graphic::XGraphic> xGraphic = svx::SignatureLineHelper::importSVG(aSvgImage);
172
0
    xShapeProps->setPropertyValue(u"Graphic"_ustr, uno::Any(xGraphic));
173
0
}
174
}
175
176
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */