ZUGFeRD: WIP Allow blocking factur-x and xrechnung invoice files with config flags

This commit is contained in:
Jonathan Jenne
2022-11-16 16:33:35 +01:00
parent f4adba98eb
commit 0410e11b59
15 changed files with 146 additions and 52 deletions

View File

@@ -8,42 +8,87 @@ Imports DigitalData.Modules.Logging
Imports GdPicture14
Public Class ZUGFeRDInterface
Private _logConfig As LogConfig
Private _logger As Logger
Private ReadOnly _logConfig As LogConfig
Private ReadOnly _logger As Logger
Private ReadOnly _Options As ZugferdOptions
Private ReadOnly ValidFilenames As New List(Of String) From {
PDFEmbeds.ZUGFERD_XML_FILENAME.ToUpper,
PDFEmbeds.FACTUR_X_XML_FILENAME_DE.ToUpper,
PDFEmbeds.FACTUR_X_XML_FILENAME_FR.ToUpper
}
Private AllowedFilenames As New List(Of String)
Public Enum ErrorType
NoValidFile
NoZugferd
NoValidZugferd
MissingProperties
UnsupportedFormat
UnknownError
End Enum
Public ReadOnly Property FileGroup As FileGroups
Public ReadOnly Property PropertyValues As PropertyValues
Public Sub New(LogConfig As LogConfig, GDPictureKey As String)
_logConfig = LogConfig
Public Class ZugferdOptions
Public Property AllowFacturX_Filename As Boolean = True
Public Property AllowXRechnung_Filename As Boolean = True
End Class
''' <summary>
''' Create a new instance of ZUGFeRDInterface
''' </summary>
''' <param name="pLogConfig">A LogConfig object</param>
''' <param name="pGDPictureKey">A valid GDPicture License</param>
''' <param name="pOptions">Optional parameters to control various settings</param>
Public Sub New(pLogConfig As LogConfig, pGDPictureKey As String, Optional pOptions As ZugferdOptions = Nothing)
_logConfig = pLogConfig
_logger = _logConfig.GetLogger()
If pOptions Is Nothing Then
_Options = New ZugferdOptions()
Else
_Options = pOptions
End If
ApplyFilenameOptions(_Options)
FileGroup = New FileGroups(_logConfig)
PropertyValues = New PropertyValues(_logConfig)
Try
Dim oLicenseManager As New LicenseManager
oLicenseManager.RegisterKEY(GDPictureKey)
oLicenseManager.RegisterKEY(pGDPictureKey)
Catch ex As Exception
_logger.Warn("GDPicture License could not be registered!")
_logger.Error(ex)
End Try
End Sub
Private Sub ApplyFilenameOptions(pOptions As ZugferdOptions)
Dim oAllowedFilenames As List(Of String) = ValidFilenames
If pOptions.AllowFacturX_Filename = False Then
oAllowedFilenames = oAllowedFilenames.
Except(New List(Of String) From {PDFEmbeds.FACTUR_X_XML_FILENAME_FR}).ToList()
End If
If pOptions.AllowXRechnung_Filename = False Then
oAllowedFilenames = oAllowedFilenames.
Except(New List(Of String) From {PDFEmbeds.FACTUR_X_XML_FILENAME_DE}).ToList()
End If
AllowedFilenames = oAllowedFilenames
End Sub
''' <summary>
''' Validates a ZUGFeRD File and extracts the XML Document from it
''' </summary>
''' <param name="Path"></param>
''' <exception cref="ZUGFeRDExecption"></exception>
''' <returns></returns>
Public Function ExtractZUGFeRDFileWithGDPicture(Path As String) As Object
Dim oXmlDocument = ValidateZUGFeRDFileWithGDPicture(Path)
@@ -59,7 +104,6 @@ Public Class ZUGFeRDInterface
''' </summary>
''' <param name="Stream"></param>
''' <exception cref="ZUGFeRDExecption"></exception>
''' <returns></returns>
Public Function ExtractZUGFeRDFileWithGDPicture(Stream As Stream) As Object
Dim oXmlDocument = ValidateZUGFeRDFileWithGDPicture(Stream)
@@ -73,15 +117,15 @@ Public Class ZUGFeRDInterface
''' <summary>
''' Validates a ZUGFeRD File and extracts the XML Document from it
''' </summary>
''' <param name="Stream"></param>
''' <param name="pStream"></param>
''' <exception cref="ZUGFeRDExecption"></exception>
''' <returns></returns>
Public Function ValidateZUGFeRDFileWithGDPicture(Stream As Stream) As XPathDocument
''' <returns>The embedded xml data as an XPath document</returns>
Public Function ValidateZUGFeRDFileWithGDPicture(pStream As Stream) As XPathDocument
Dim oEmbedExtractor = New PDFEmbeds(_logConfig)
Dim oAllowedExtensions = New List(Of String) From {"xml"}
Try
Dim oFiles = oEmbedExtractor.Extract(Stream, oAllowedExtensions)
' Extract XML attachments only!
Dim oFiles = oEmbedExtractor.Extract(pStream, New List(Of String) From {"xml"})
' Attachments are in this case the files that are embedded into a pdf file,
' like for example the zugferd-invoice.xml file
@@ -98,12 +142,18 @@ Public Class ZUGFeRDInterface
End Try
End Function
Public Function ValidateZUGFeRDFileWithGDPicture(Path As String) As XPathDocument
''' <summary>
''' Validates a ZUGFeRD File and extracts the XML Document from it
''' </summary>
''' <param name="pPath"></param>
''' <exception cref="ZUGFeRDExecption"></exception>
''' <returns>The embedded xml data as an XPath document</returns>
Public Function ValidateZUGFeRDFileWithGDPicture(pPath As String) As XPathDocument
Dim oEmbedExtractor = New PDFEmbeds(_logConfig)
Dim oAllowedExtensions = New List(Of String) From {"xml"}
Try
Dim oFiles = oEmbedExtractor.Extract(Path, oAllowedExtensions)
' Extract XML attachments only!
Dim oFiles = oEmbedExtractor.Extract(pPath, New List(Of String) From {"xml"})
' Attachments are in this case the files that are embedded into a pdf file,
' like for example the zugferd-invoice.xml file
@@ -120,34 +170,38 @@ Public Class ZUGFeRDInterface
End Try
End Function
Private Function HandleEmbeddedFiles(Results As List(Of PDFEmbeds.EmbeddedFile)) As XPathDocument
Private Function HandleEmbeddedFiles(pResults As List(Of PDFEmbeds.EmbeddedFile)) As XPathDocument
Dim oXmlDocument As XPathDocument
If Results Is Nothing Then
If pResults Is Nothing Then
Throw New ZUGFeRDExecption(ErrorType.NoZugferd, "Datei ist keine ZUGFeRD Datei, weil die Attachments nicht gelesen werden konnten.")
End If
If Results.Count = 0 Then
If pResults.Count = 0 Then
Throw New ZUGFeRDExecption(ErrorType.NoZugferd, "Datei ist keine ZUGFeRD Datei, weil sie keine Attachments enthält.")
End If
Dim oValidFilenames As New List(Of String) From {
PDFEmbeds.ZUGFERD_XML_FILENAME.ToUpper,
PDFEmbeds.FACTUR_X_XML_FILENAME_DE.ToUpper,
PDFEmbeds.FACTUR_X_XML_FILENAME_FR.ToUpper
}
' Find the first file which filename matches the valid filenames for embedded invoice files
Dim oFoundResult As PDFEmbeds.EmbeddedFile = Results.
Where(Function(result) oValidFilenames.Contains(result.FileName.ToUpper)).
Dim oValidResult As PDFEmbeds.EmbeddedFile = pResults.
Where(Function(result) ValidFilenames.Contains(result.FileName.ToUpper)).
FirstOrDefault()
If oFoundResult Is Nothing Then
Throw New ZUGFeRDExecption(ErrorType.NoZugferd, "Datei ist keine ZUGFeRD Datei, weil die zugferd-invoice.xml nicht gefunden wurde.")
If oValidResult Is Nothing Then
Throw New ZUGFeRDExecption(ErrorType.NoZugferd, "Datei ist keine ZUGFeRD Datei, weil keine entsprechende XML-Datei gefunden wurde.")
End If
' Search the embedded files for the ones which are allowed as per the configuration.
' The config might say, allow ZUGFeRD but not Factur-X.
Dim oAllowedResult As PDFEmbeds.EmbeddedFile = pResults.
Where(Function(result) AllowedFilenames.Contains(result.FileName.ToUpper)).
FirstOrDefault()
If oAllowedResult Is Nothing Then
Throw New ZUGFeRDExecption(ErrorType.UnsupportedFormat, "Datei ist eine ZUGFeRD Datei, aber das Format wird nicht unterstützt.")
End If
Try
Using oStream As New MemoryStream(oFoundResult.FileContents)
Using oStream As New MemoryStream(oAllowedResult.FileContents)
oXmlDocument = New XPathDocument(oStream)
End Using
@@ -163,9 +217,9 @@ Public Class ZUGFeRDInterface
End Try
End Function
Public Function SerializeZUGFeRDDocument(Document As XPathDocument) As Object
Public Function SerializeZUGFeRDDocument(pDocument As XPathDocument) As Object
Try
Dim oNavigator As XPathNavigator = Document.CreateNavigator()
Dim oNavigator As XPathNavigator = pDocument.CreateNavigator()
Dim oReader As XmlReader
Dim oResult = Nothing

View File

@@ -28,7 +28,7 @@ Public Class PDFEmbeds
Public Function Extract(FilePath As String, AllowedExtensions As List(Of String)) As List(Of EmbeddedFile)
Dim oFile As New List(Of EmbeddedFile)
Dim oFileInfo As FileInfo
Dim oExtensions = AllowedExtensions.ConvertAll(New Converter(Of String, String)(Function(ext) ext.ToUpper))
Dim oExtensions = AllowedExtensions.Select(Function(ext) ext.ToUpper).ToList()
Logger.Debug("Extracting embedded files from [{0}]", FilePath)
@@ -69,7 +69,7 @@ Public Class PDFEmbeds
''' <param name="AllowedExtensions">List of allowed extensions to be extracted</param>
Public Function Extract(Stream As Stream, AllowedExtensions As List(Of String)) As List(Of EmbeddedFile)
Dim oResults As New List(Of EmbeddedFile)
Dim oExtensions = AllowedExtensions.ConvertAll(New Converter(Of String, String)(Function(ext) ext.ToUpper))
Dim oExtensions = AllowedExtensions.Select(Function(ext) ext.ToUpper).ToList()
Logger.Debug("Extracting embedded files from stream")