From 825ae79b5d351f5cd8b2077a91fc6e1ee0cc5644 Mon Sep 17 00:00:00 2001 From: Marten Rebane <54431068+martenrebane@users.noreply.github.com> Date: Fri, 14 Jun 2024 11:16:11 +0300 Subject: [PATCH] Fix Xades files handling --- MoppApp/MoppApp/ContainerActions.swift | 4 +- MoppApp/MoppApp/ContainerViewController.swift | 37 ++++++++++++++----- MoppApp/MoppApp/MimeTypeExtractor.swift | 26 +++++++++++++ MoppApp/MoppApp/PreviewActions.swift | 6 +-- .../RecentContainersViewController.swift | 4 +- MoppApp/MoppApp/SignatureUtil.swift | 9 +++++ MoppApp/MoppApp/SivaUtil.swift | 3 +- 7 files changed, 71 insertions(+), 18 deletions(-) diff --git a/MoppApp/MoppApp/ContainerActions.swift b/MoppApp/MoppApp/ContainerActions.swift index bdc7e9176..1d0d402f8 100644 --- a/MoppApp/MoppApp/ContainerActions.swift +++ b/MoppApp/MoppApp/ContainerActions.swift @@ -91,7 +91,7 @@ extension ContainerActions where Self: UIViewController { if (isAsicOrPadesContainer || isCdocContainer) && urls.count == 1 { SiVaUtil.setIsSentToSiva(isSent: false) - if let firstUrl = urls.first, (firstUrl.pathExtension == "asics" || firstUrl.pathExtension == "scs") || firstUrl.pathExtension == "ddoc" || (firstUrl.pathExtension == "pdf" && SiVaUtil.isSignedPDF(url: firstUrl as CFURL)) || MimeTypeExtractor.isCadesContainer(filePath: firstUrl) { + if let firstUrl = urls.first, ((firstUrl.pathExtension == "asics" || firstUrl.pathExtension == "scs") && !MimeTypeExtractor.isXadesContainer(filePath: firstUrl)) || firstUrl.pathExtension == "ddoc" || (firstUrl.pathExtension == "pdf" && SiVaUtil.isSignedPDF(url: firstUrl as CFURL)) || MimeTypeExtractor.isCadesContainer(filePath: firstUrl) { if self?.getTopViewController() is FileImportProgressViewController { self?.dismiss(animated: true, completion: { SiVaUtil.displaySendingToSiVaDialog { hasAgreed in @@ -165,7 +165,7 @@ extension ContainerActions where Self: UIViewController { let fileURL = URL(fileURLWithPath: newFilePath) let fileExtension = fileURL.pathExtension let isSignedPDF = SiVaUtil.isSignedPDF(url: fileURL as CFURL) - if (forbiddenFileExtensions.contains(fileExtension) || isSignedPDF || MimeTypeExtractor.isCadesContainer(filePath: fileURL)) { + if (forbiddenFileExtensions.contains(fileExtension) || isSignedPDF || (MimeTypeExtractor.isCadesContainer(filePath: fileURL) && !MimeTypeExtractor.isXadesContainer(filePath: fileURL))) { self.openContainer(url: url, newFilePath: newFilePath, fileName: fileName, landingViewController: landingViewController, navController: navController, isEmptyFileImported: isEmptyFileImported, isSendingToSivaAgreed: isSendingToSivaAgreed) { error in failure(error) } diff --git a/MoppApp/MoppApp/ContainerViewController.swift b/MoppApp/MoppApp/ContainerViewController.swift index 800883d63..6509d11d9 100644 --- a/MoppApp/MoppApp/ContainerViewController.swift +++ b/MoppApp/MoppApp/ContainerViewController.swift @@ -75,8 +75,8 @@ class ContainerViewController : MoppViewController, ContainerActions, PreviewAct let landingViewController = LandingViewController.shared! var isAsicContainer = LandingViewController.shared.containerType == .asic var isEmptyFileWarningSet = false - var isAsicsFileWarningSet = false var isCadesWarningSet = false + var isXadesWarningSet = false var asicsSignatures = [MoppLibSignature]() var asicsDataFiles = [MoppLibDataFile]() @@ -241,8 +241,8 @@ class ContainerViewController : MoppViewController, ContainerActions, PreviewAct let asicContainer = self.containerViewDelegate?.getContainer() checkEmptyFilesInContainer(asicContainer: asicContainer) - if isAsicsContainer() && !isAsicsFileWarningSet { - handleAsicsContainerMessage() + if isAsicsContainer() && !isXadesWarningSet { + handleXadesContainerMessage(asicContainer: asicContainer) } if isAsicContainer { @@ -351,12 +351,16 @@ class ContainerViewController : MoppViewController, ContainerActions, PreviewAct } } - private func handleAsicsContainerMessage() { - let asicsFileNotification = NotificationMessage(isSuccess: false, text: L(.containerAsicsWarning)) - if !self.notifications.contains(where: { $0 == asicsFileNotification }) { - self.notifications.append(asicsFileNotification) + private func handleXadesContainerMessage(asicContainer: MoppLibContainer?) { + guard let container = asicContainer else { return } + let isXades = SignatureUtil.isXades(signatures: container.signatures) + if isXades { + let xadesNotification = NotificationMessage(isSuccess: false, text: L(.containerAsicsWarning)) + if !self.notifications.contains(where: { $0 == xadesNotification }) { + self.notifications.append(xadesNotification) + } + isXadesWarningSet = true } - isAsicsFileWarningSet = true } private func checkIsCades(asicContainer: MoppLibContainer?) { @@ -370,6 +374,15 @@ class ContainerViewController : MoppViewController, ContainerActions, PreviewAct isCadesWarningSet = true } } + + static func isXades(signatures: [Any]) -> Bool { + return signatures.contains { signature in + if let sig = signature as? MoppLibSignature { + return sig.signatureFormat.lowercased().contains("bes") + } + return false + } + } func setSections() { if isSignaturesEmpty && isAsicContainer { @@ -775,7 +788,8 @@ extension ContainerViewController : UITableViewDataSource { let nserror = error as NSError? if nserror != nil && nserror?.code == Int(MoppLibErrorCode.moppLibErrorNoInternetConnection.rawValue) { let pathExtension = URL(string: containerFilePath)?.pathExtension - if pathExtension == "asics" || pathExtension == "scs" { + let asicContainer: MoppLibContainer? = self.containerViewDelegate?.getContainer() + if (pathExtension == "asics" || pathExtension == "scs") && !ContainerViewController.isXades(signatures: asicContainer?.signatures ?? []) { SiVaUtil.displaySendingToSiVaDialog { hasAgreed in if hasAgreed { SiVaUtil.setIsSentToSiva(isSent: hasAgreed) @@ -1111,7 +1125,10 @@ extension ContainerViewController : UITableViewDelegate { } } else { - if isAsicsContainer() { + let asicContainer: MoppLibContainer? = self.containerViewDelegate?.getContainer() + if isAsicsContainer() && ContainerViewController.isXades(signatures: asicContainer?.signatures ?? []) { + sections = ContainerViewController.sectionsWithTimestamp + } else if isAsicsContainer() { sections = isSendingToSivaAgreed ? ContainerViewController.sectionsWithTimestamp : ContainerViewController.sectionsWithTimestampNoSignatures } else { diff --git a/MoppApp/MoppApp/MimeTypeExtractor.swift b/MoppApp/MoppApp/MimeTypeExtractor.swift index c5d8b895c..dd2b90f9b 100644 --- a/MoppApp/MoppApp/MimeTypeExtractor.swift +++ b/MoppApp/MoppApp/MimeTypeExtractor.swift @@ -51,6 +51,14 @@ class MimeTypeExtractor { return false } + public static func isXadesContainer(filePath: URL) -> Bool { + if isZipFile(filePath: filePath) { + return containerHasSignatureXmlFiles(filePath: filePath) + } + + return false + } + public static func getMimeTypeFromContainer(filePath: URL) -> String { var mimetype: String = "" @@ -147,6 +155,24 @@ class MimeTypeExtractor { return false } + private static func containerHasSignatureXmlFiles(filePath: URL) -> Bool { + do { + let archive = try Archive(url: filePath, accessMode: .read) + + for entry in archive { + let entryUrl = URL(fileURLWithPath: entry.path) + if entryUrl.lastPathComponent.contains("signatures.xml") { + return true + } + } + } catch (let archiveError) { + printLog("Unable to open archive: \(archiveError.localizedDescription)") + return false + } + + return false + } + private static func unZipFile(filePath: URL, fileName: String) -> URL? { let outputPath = MoppFileManager.shared.tempCacheDirectoryPath().appendingPathComponent(filePath.lastPathComponent).deletingPathExtension() diff --git a/MoppApp/MoppApp/PreviewActions.swift b/MoppApp/MoppApp/PreviewActions.swift index d1a68b12a..883bacc34 100644 --- a/MoppApp/MoppApp/PreviewActions.swift +++ b/MoppApp/MoppApp/PreviewActions.swift @@ -52,7 +52,7 @@ extension PreviewActions where Self: ContainerViewController { let destinationPathURL = URL(fileURLWithPath: destinationPath) SiVaUtil.setIsSentToSiva(isSent: false) - if SiVaUtil.isDocumentSentToSiVa(fileUrl: destinationPathURL) { + if (SiVaUtil.isDocumentSentToSiVa(fileUrl: destinationPathURL) && !MimeTypeExtractor.isXadesContainer(filePath: destinationPathURL)) { SiVaUtil.displaySendingToSiVaDialog { hasAgreed in if (destinationPathURL.pathExtension == "ddoc" || destinationPathURL.pathExtension == "pdf") && !hasAgreed { self.updateState(.opened) @@ -101,10 +101,10 @@ extension PreviewActions where Self: ContainerViewController { return } - let fileExtension = URL(fileURLWithPath: filePath).pathExtension.lowercased() + let fileExtension = url.pathExtension.lowercased() SiVaUtil.setIsSentToSiva(isSent: false) - if fileExtension != "pdf" && SiVaUtil.isDocumentSentToSiVa(fileUrl: URL(fileURLWithPath: filePath)) { + if (fileExtension != "pdf" && SiVaUtil.isDocumentSentToSiVa(fileUrl: URL(fileURLWithPath: filePath)) && !MimeTypeExtractor.isXadesContainer(filePath: url)) { SiVaUtil.displaySendingToSiVaDialog { hasAgreed in if hasAgreed { openContentPreviewDocument(filePath) diff --git a/MoppApp/MoppApp/RecentContainersViewController.swift b/MoppApp/MoppApp/RecentContainersViewController.swift index 760724be9..09a7e73cf 100644 --- a/MoppApp/MoppApp/RecentContainersViewController.swift +++ b/MoppApp/MoppApp/RecentContainersViewController.swift @@ -211,10 +211,10 @@ extension RecentContainersViewController : UITableViewDelegate { if ext.isAsicContainerExtension || ext.isPdfContainerExtension { let containerPathURL = path SiVaUtil.setIsSentToSiva(isSent: false) - if SiVaUtil.isDocumentSentToSiVa(fileUrl: containerPathURL) || (containerPathURL.pathExtension == "asics" || containerPathURL.pathExtension == "scs") { + if (SiVaUtil.isDocumentSentToSiVa(fileUrl: containerPathURL) || (containerPathURL.pathExtension == "asics" || containerPathURL.pathExtension == "scs")) && !MimeTypeExtractor.isXadesContainer(filePath: containerPathURL) { SiVaUtil.displaySendingToSiVaDialog { hasAgreed in if (containerPathURL.pathExtension == "ddoc" || containerPathURL.pathExtension == "pdf" || - MimeTypeExtractor.isCadesContainer(filePath: containerPathURL)) && !hasAgreed { + (MimeTypeExtractor.isCadesContainer(filePath: containerPathURL) && !MimeTypeExtractor.isXadesContainer(filePath: containerPathURL))) && !hasAgreed { return } self.openContainer(containerPath: path.path, navController: navController, isSendingToSivaAgreed: hasAgreed) diff --git a/MoppApp/MoppApp/SignatureUtil.swift b/MoppApp/MoppApp/SignatureUtil.swift index 1b6345290..5587cdf82 100644 --- a/MoppApp/MoppApp/SignatureUtil.swift +++ b/MoppApp/MoppApp/SignatureUtil.swift @@ -36,6 +36,15 @@ class SignatureUtil { return false } + static func isXades(signatures: [Any]) -> Bool { + return signatures.contains { signature in + if let sig = signature as? MoppLibSignature { + return sig.signatureFormat.lowercased().contains("bes") + } + return false + } + } + static func getSignatures(filePath: URL) -> [Any] { do { let container = try MoppLibContainerActions.sharedInstance().openContainer(withPath: filePath.path) diff --git a/MoppApp/MoppApp/SivaUtil.swift b/MoppApp/MoppApp/SivaUtil.swift index 4b2b0cbed..efb1a3b49 100644 --- a/MoppApp/MoppApp/SivaUtil.swift +++ b/MoppApp/MoppApp/SivaUtil.swift @@ -37,7 +37,8 @@ class SiVaUtil { } let isCades = MimeTypeExtractor.isCadesContainer(filePath: fileLocation) - let isSentToSiva = containerTypes.contains(containerType) || isCades + let isXades = MimeTypeExtractor.isXadesContainer(filePath: fileLocation) + let isSentToSiva = (containerTypes.contains(containerType) && !isXades) || isCades return isSentToSiva }