Skip to content

Commit bef64ee

Browse files
authored
Filename validator (#2984)
* WIP Signed-off-by: Milen Pivchev <[email protected]> * WIP Signed-off-by: Milen Pivchev <[email protected]> * WIP Signed-off-by: Milen Pivchev <[email protected]> * File provider support Signed-off-by: Milen Pivchev <[email protected]> * WIP Signed-off-by: Milen Pivchev <[email protected]> * WIP Signed-off-by: Milen Pivchev <[email protected]> * Merge fixes Signed-off-by: Milen Pivchev <[email protected]> * WIP Signed-off-by: Milen Pivchev <[email protected]> * WIP Signed-off-by: Milen Pivchev <[email protected]> * Scanner Signed-off-by: Milen Pivchev <[email protected]> * WIP Signed-off-by: Milen Pivchev <[email protected]> * WIP Signed-off-by: Milen Pivchev <[email protected]> * Add asset upload check Signed-off-by: Milen Pivchev <[email protected]> * WIP Signed-off-by: Milen Pivchev <[email protected]> * Fix PR Signed-off-by: Milen Pivchev <[email protected]> * Update NCBrand.swift Signed-off-by: Milen Pivchev <[email protected]> --------- Signed-off-by: Milen Pivchev <[email protected]>
1 parent 0f0c39b commit bef64ee

28 files changed

+335
-538
lines changed

File Provider Extension/FileProviderData.swift

+2-2
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class fileProviderData: NSObject {
9191
homeServerUrl = utilityFileSystem.getHomeServer(urlBase: activeAccount.urlBase, userId: activeAccount.userId)
9292

9393
NCManageDatabase.shared.setCapabilities(account: account)
94-
NextcloudKit.shared.setup(account: activeAccount.account, user: activeAccount.user, userId: activeAccount.userId, password: NCKeychain().getPassword(account: activeAccount.account), urlBase: activeAccount.urlBase, userAgent: userAgent, nextcloudVersion: NCGlobal.shared.capabilityServerVersionMajor, groupIdentifier: NCBrandOptions.shared.capabilitiesGroup, delegate: NCNetworking.shared)
94+
NextcloudKit.shared.setup(account: activeAccount.account, user: activeAccount.user, userId: activeAccount.userId, password: NCKeychain().getPassword(account: activeAccount.account), urlBase: activeAccount.urlBase, userAgent: userAgent, nextcloudVersion: NCGlobal.shared.capabilityServerVersionMajor, delegate: NCNetworking.shared)
9595
NCNetworking.shared.delegate = providerExtension as? NCNetworkingDelegate
9696

9797
return tableAccount.init(value: activeAccount)
@@ -114,7 +114,7 @@ class fileProviderData: NSObject {
114114

115115
NCManageDatabase.shared.setCapabilities(account: account)
116116

117-
NextcloudKit.shared.setup(account: activeAccount.account, user: activeAccount.user, userId: activeAccount.userId, password: NCKeychain().getPassword(account: activeAccount.account), urlBase: activeAccount.urlBase, userAgent: userAgent, nextcloudVersion: NCGlobal.shared.capabilityServerVersionMajor, groupIdentifier: NCBrandOptions.shared.capabilitiesGroup, delegate: NCNetworking.shared)
117+
NextcloudKit.shared.setup(account: activeAccount.account, user: activeAccount.user, userId: activeAccount.userId, password: NCKeychain().getPassword(account: activeAccount.account), urlBase: activeAccount.urlBase, userAgent: userAgent, nextcloudVersion: NCGlobal.shared.capabilityServerVersionMajor, delegate: NCNetworking.shared)
118118
NCNetworking.shared.delegate = providerExtension as? NCNetworkingDelegate
119119

120120
return tableAccount.init(value: activeAccount)

File Provider Extension/FileProviderExtension+Actions.swift

+6-2
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ extension FileProviderExtension {
5454
}
5555
}
5656
} else {
57-
completionHandler(nil, NSFileProviderError(.serverUnreachable))
57+
completionHandler(nil, NSFileProviderError(.filenameCollision))
5858
}
5959
}
6060
}
@@ -70,7 +70,7 @@ extension FileProviderExtension {
7070
let fileName = metadata.fileName
7171

7272
NextcloudKit.shared.deleteFileOrFolder(serverUrlFileName: serverUrlFileName, account: metadata.account) { account, error in
73-
if error == .success { // || error == kOCErrorServerPathNotFound {
73+
if error == .success {
7474
let fileNamePath = self.utilityFileSystem.getDirectoryProviderStorageOcId(itemIdentifier.rawValue)
7575

7676
do {
@@ -122,6 +122,8 @@ extension FileProviderExtension {
122122
let item = FileProviderItem(metadata: metadata, parentItemIdentifier: parentItemIdentifier)
123123

124124
completionHandler(item, nil)
125+
} else if error.errorCode == NCGlobal.shared.errorBadRequest {
126+
completionHandler(nil, NSFileProviderError(.noSuchItem, userInfo: [NSLocalizedDescriptionKey: error.errorDescription, NSLocalizedFailureReasonErrorKey: ""]))
125127
} else {
126128
completionHandler(nil, NSFileProviderError(.serverUnreachable))
127129
}
@@ -161,6 +163,8 @@ extension FileProviderExtension {
161163
}
162164
let item = FileProviderItem(metadata: tableMetadata.init(value: metadata), parentItemIdentifier: parentItemIdentifier)
163165
completionHandler(item, nil)
166+
} else if error.errorCode == NCGlobal.shared.errorBadRequest {
167+
completionHandler(nil, NSFileProviderError(.noSuchItem, userInfo: [NSLocalizedDescriptionKey: error.errorDescription, NSLocalizedFailureReasonErrorKey: ""]))
164168
} else {
165169
completionHandler(nil, NSFileProviderError(.serverUnreachable))
166170
}

Nextcloud.xcodeproj/project.pbxproj

+2-22
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,6 @@
197197
F70CAE3A1F8CF31A008125FD /* NCEndToEndEncryption.m in Sources */ = {isa = PBXBuildFile; fileRef = F70CAE391F8CF31A008125FD /* NCEndToEndEncryption.m */; };
198198
F70CEF5623E9C7E50007035B /* UIColor+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70CEF5523E9C7E50007035B /* UIColor+Extension.swift */; };
199199
F70D7C3725FFBF82002B9E34 /* NCCollectionViewCommon.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70D7C3525FFBF81002B9E34 /* NCCollectionViewCommon.swift */; };
200-
F70D87CF25EE6E58008CBBBD /* NCRenameFile.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F70D87CD25EE6E58008CBBBD /* NCRenameFile.storyboard */; };
201-
F70D87D025EE6E58008CBBBD /* NCRenameFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70D87CE25EE6E58008CBBBD /* NCRenameFile.swift */; };
202200
F70D8D8124A4A9BF000A5756 /* NCNetworkingProcess.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70D8D8024A4A9BF000A5756 /* NCNetworkingProcess.swift */; };
203201
F710D1F52405770F00A6033D /* NCViewerPDF.swift in Sources */ = {isa = PBXBuildFile; fileRef = F710D1F42405770F00A6033D /* NCViewerPDF.swift */; };
204202
F710D2022405826100A6033D /* NCViewer+Menu.swift in Sources */ = {isa = PBXBuildFile; fileRef = F710D2012405826100A6033D /* NCViewer+Menu.swift */; };
@@ -712,8 +710,6 @@
712710
F79B646226CA661600838ACA /* UIControl+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F79B645F26CA661600838ACA /* UIControl+Extension.swift */; };
713711
F79B646326CA661600838ACA /* UIControl+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F79B645F26CA661600838ACA /* UIControl+Extension.swift */; };
714712
F79B869B265E19D40085C0E0 /* NSMutableAttributedString+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = F79B869A265E19D40085C0E0 /* NSMutableAttributedString+Extension.swift */; };
715-
F79EC77F26316193004E59D6 /* NCRenameFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = F70D87CE25EE6E58008CBBBD /* NCRenameFile.swift */; };
716-
F79EC784263161BA004E59D6 /* NCRenameFile.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F70D87CD25EE6E58008CBBBD /* NCRenameFile.storyboard */; };
717713
F79EC78926316AC4004E59D6 /* NCPopupViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F702F30725EE5D47008F8E80 /* NCPopupViewController.swift */; };
718714
F79EDAA326B004980007D134 /* NCPlayerToolBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = F79EDA9F26B004980007D134 /* NCPlayerToolBar.swift */; };
719715
F79EDAA526B004980007D134 /* NCPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = F79EDAA126B004980007D134 /* NCPlayer.swift */; };
@@ -1217,8 +1213,6 @@
12171213
F70CAE391F8CF31A008125FD /* NCEndToEndEncryption.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NCEndToEndEncryption.m; sourceTree = "<group>"; };
12181214
F70CEF5523E9C7E50007035B /* UIColor+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Extension.swift"; sourceTree = "<group>"; };
12191215
F70D7C3525FFBF81002B9E34 /* NCCollectionViewCommon.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCCollectionViewCommon.swift; sourceTree = "<group>"; };
1220-
F70D87CD25EE6E58008CBBBD /* NCRenameFile.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = NCRenameFile.storyboard; sourceTree = "<group>"; };
1221-
F70D87CE25EE6E58008CBBBD /* NCRenameFile.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NCRenameFile.swift; sourceTree = "<group>"; };
12221216
F70D8D8024A4A9BF000A5756 /* NCNetworkingProcess.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NCNetworkingProcess.swift; sourceTree = "<group>"; };
12231217
F70F2BA4225F2D8900EBB73E /* ZIPFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ZIPFoundation.framework; path = Carthage/Build/iOS/ZIPFoundation.framework; sourceTree = "<group>"; };
12241218
F70F96AF2874394B006C8379 /* Nextcloud-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Nextcloud-Bridging-Header.h"; sourceTree = "<group>"; };
@@ -2082,15 +2076,6 @@
20822076
path = Color;
20832077
sourceTree = "<group>";
20842078
};
2085-
F70D87CC25EE6E58008CBBBD /* Rename file */ = {
2086-
isa = PBXGroup;
2087-
children = (
2088-
F70D87CD25EE6E58008CBBBD /* NCRenameFile.storyboard */,
2089-
F70D87CE25EE6E58008CBBBD /* NCRenameFile.swift */,
2090-
);
2091-
path = "Rename file";
2092-
sourceTree = "<group>";
2093-
};
20942079
F713418B2597513800768D21 /* PushNotification */ = {
20952080
isa = PBXGroup;
20962081
children = (
@@ -2980,7 +2965,6 @@
29802965
F7381ED9218218A4000B1560 /* Offline */,
29812966
F713418B2597513800768D21 /* PushNotification */,
29822967
F765F72E25237E3F00391DBE /* Recent */,
2983-
F70D87CC25EE6E58008CBBBD /* Rename file */,
29842968
F7CADB3D23CCDDA1000EEC78 /* RichWorkspace */,
29852969
F76882042C0DD1E7001CF441 /* Settings */,
29862970
F758B41E212C516300515F55 /* Scan document */,
@@ -3668,7 +3652,6 @@
36683652
F7145A231D12E3B700CAFEEC /* Localizable.strings in Resources */,
36693653
F746EC51273906C40052598D /* NCViewCertificateDetails.storyboard in Resources */,
36703654
F76C26A62850D3A500E42BDF /* Images.xcassets in Resources */,
3671-
F79EC784263161BA004E59D6 /* NCRenameFile.storyboard in Resources */,
36723655
F714805E262ED52900693E51 /* NCSectionFooter.xib in Resources */,
36733656
F700222D1EC479840080073F /* Custom.xcassets in Resources */,
36743657
);
@@ -3714,7 +3697,6 @@
37143697
F702F2F125EE5CDB008F8E80 /* NCLogin.storyboard in Resources */,
37153698
F723985C253C95CE00257F49 /* NCViewerRichdocument.storyboard in Resources */,
37163699
F758B45A212C564000515F55 /* NCScan.storyboard in Resources */,
3717-
F70D87CF25EE6E58008CBBBD /* NCRenameFile.storyboard in Resources */,
37183700
F765F73225237E3F00391DBE /* NCRecent.storyboard in Resources */,
37193701
F78F74342163757000C2ADAD /* NCTrash.storyboard in Resources */,
37203702
F702F30225EE5D2C008F8E80 /* english.txt in Resources */,
@@ -4046,7 +4028,6 @@
40464028
F76D364728A4F8BF00214537 /* NCActivityIndicator.swift in Sources */,
40474029
F73EF7CA2B0225610087E6E9 /* NCManageDatabase+PhotoLibrary.swift in Sources */,
40484030
F749B654297B0F2400087535 /* NCManageDatabase+Avatar.swift in Sources */,
4049-
F79EC77F26316193004E59D6 /* NCRenameFile.swift in Sources */,
40504031
AF22B208277B4E4C00DAB0CC /* NCCreateFormUploadConflictCell.swift in Sources */,
40514032
F74C86382AEFBE64009A1D4A /* NCImageCache.swift in Sources */,
40524033
F73EF7C22B02250B0087E6E9 /* NCManageDatabase+GPS.swift in Sources */,
@@ -4234,7 +4215,6 @@
42344215
F702F30825EE5D47008F8E80 /* NCPopupViewController.swift in Sources */,
42354216
F733598125C1C188002ABA72 /* NCAskAuthorization.swift in Sources */,
42364217
370D26AF248A3D7A00121797 /* NCCellProtocol.swift in Sources */,
4237-
F70D87D025EE6E58008CBBBD /* NCRenameFile.swift in Sources */,
42384218
F768822C2C0DD1E7001CF441 /* NCKeychain.swift in Sources */,
42394219
F71CD6CA2930D7B1006C95C1 /* NCApplicationHandle.swift in Sources */,
42404220
F73EF7D72B0226080087E6E9 /* NCManageDatabase+Tip.swift in Sources */,
@@ -5778,8 +5758,8 @@
57785758
isa = XCRemoteSwiftPackageReference;
57795759
repositoryURL = "https://github.com/nextcloud/NextcloudKit";
57805760
requirement = {
5781-
kind = exactVersion;
5782-
version = 4.0.6;
5761+
branch = "filename-validator";
5762+
kind = branch;
57835763
};
57845764
};
57855765
F788ECC5263AAAF900ADC67F /* XCRemoteSwiftPackageReference "MarkdownKit" */ = {

Share/NCShareExtension+DataSource.swift

+5-2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ extension NCShareExtension: UICollectionViewDelegate {
3535
showAlert(title: "_info_", description: "_e2e_goto_settings_for_enable_")
3636
}
3737

38+
if let fileNameError = FileNameValidator.shared.checkFileName(metadata.fileNameView) {
39+
present(UIAlertController.warning(message: "\(fileNameError.errorDescription) \(NSLocalizedString("_please_rename_file_", comment: ""))"), animated: true)
40+
return
41+
}
42+
3843
self.serverUrl = serverUrl
3944
reloadDatasource(withLoadFolder: true)
4045
setNavigationBar(navigationTitle: metadata.fileNameView)
@@ -84,8 +89,6 @@ extension NCShareExtension: UICollectionViewDataSource {
8489
return UICollectionViewCell()
8590
}
8691

87-
cell.listCellDelegate = self
88-
8992
cell.fileObjectId = metadata.ocId
9093
cell.indexPath = indexPath
9194
cell.fileUser = metadata.ownerId

Share/NCShareExtension+Files.swift

+1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
import Foundation
2525
import UniformTypeIdentifiers
26+
import NextcloudKit
2627

2728
extension NCShareExtension {
2829
@objc func reloadDatasource(withLoadFolder: Bool) {

Share/NCShareExtension+NCDelegate.swift

+31-48
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,30 @@ extension NCShareExtension: NCAccountRequestDelegate {
9393

9494
reloadDatasource(withLoadFolder: true)
9595
setNavigationBar(navigationTitle: NCBrandOptions.shared.brand)
96+
97+
FileNameValidator.shared.setup(
98+
forbiddenFileNames: NCGlobal.shared.capabilityForbiddenFileNames,
99+
forbiddenFileNameBasenames: NCGlobal.shared.capabilityForbiddenFileNameBasenames,
100+
forbiddenFileNameCharacters: NCGlobal.shared.capabilityForbiddenFileNameCharacters,
101+
forbiddenFileNameExtensions: NCGlobal.shared.capabilityForbiddenFileNameExtensions
102+
)
103+
}
104+
}
105+
106+
extension NCShareExtension: NCCreateFormUploadConflictDelegate {
107+
func dismissCreateFormUploadConflict(metadatas: [tableMetadata]?) {
108+
guard let metadatas = metadatas else {
109+
uploadStarted = false
110+
uploadMetadata.removeAll()
111+
return
112+
}
113+
114+
self.uploadMetadata.append(contentsOf: metadatas)
115+
self.upload()
96116
}
97117
}
98118

99-
extension NCShareExtension: NCShareCellDelegate, NCRenameFileDelegate, NCListCellDelegate {
119+
extension NCShareExtension: NCShareCellDelegate {
100120
func removeFile(named fileName: String) {
101121
guard let index = self.filesName.firstIndex(of: fileName) else {
102122
return showAlert(title: "_file_not_found_", description: fileName)
@@ -110,54 +130,17 @@ extension NCShareExtension: NCShareCellDelegate, NCRenameFileDelegate, NCListCel
110130
}
111131

112132
func renameFile(named fileName: String) {
113-
guard let vcRename = UIStoryboard(name: "NCRenameFile", bundle: nil).instantiateInitialViewController() as? NCRenameFile else { return }
114-
115-
let resultInternalType = NextcloudKit.shared.nkCommonInstance.getInternalType(fileName: fileName, mimeType: "", directory: false)
116-
vcRename.delegate = self
117-
vcRename.fileName = fileName
118-
vcRename.indexPath = IndexPath()
119-
if let previewImage = UIImage.downsample(imageAt: URL(fileURLWithPath: NSTemporaryDirectory() + fileName), to: CGSize(width: 140, height: 140)) {
120-
vcRename.imagePreview = previewImage
121-
} else {
122-
vcRename.imagePreview = UIImage(named: resultInternalType.iconName) ?? NCImageCache.images.file
133+
let alert = UIAlertController.renameFile(fileName: fileName) { [self] newFileName in
134+
guard let fileIx = self.filesName.firstIndex(of: fileName),
135+
!self.filesName.contains(newFileName),
136+
utilityFileSystem.moveFile(atPath: (NSTemporaryDirectory() + fileName), toPath: (NSTemporaryDirectory() + newFileName)) else {
137+
return showAlert(title: "_single_file_conflict_title_", description: "'\(fileName)' -> '\(newFileName)'")
138+
}
139+
140+
filesName[fileIx] = newFileName
141+
tableView.reloadData()
123142
}
124143

125-
let popup = NCPopupViewController(contentController: vcRename, popupWidth: vcRename.width, popupHeight: vcRename.height)
126-
127-
self.present(popup, animated: true)
128-
}
129-
130-
func rename(fileName: String, fileNameNew: String) {
131-
guard fileName != fileNameNew else { return }
132-
guard let fileIx = self.filesName.firstIndex(of: fileName),
133-
!self.filesName.contains(fileNameNew),
134-
utilityFileSystem.moveFile(atPath: (NSTemporaryDirectory() + fileName), toPath: (NSTemporaryDirectory() + fileNameNew)) else {
135-
return showAlert(title: "_single_file_conflict_title_", description: "'\(fileName)' -> '\(fileNameNew)'")
136-
}
137-
138-
filesName[fileIx] = fileNameNew
139-
tableView.reloadData()
140-
}
141-
142-
func tapShareListItem(with objectId: String, indexPath: IndexPath, sender: Any) {
143-
}
144-
145-
func tapMoreListItem(with objectId: String, namedButtonMore: String, image: UIImage?, indexPath: IndexPath, sender: Any) {
146-
}
147-
148-
func longPressListItem(with objectId: String, indexPath: IndexPath, gestureRecognizer: UILongPressGestureRecognizer) {
149-
}
150-
}
151-
152-
extension NCShareExtension: NCCreateFormUploadConflictDelegate {
153-
func dismissCreateFormUploadConflict(metadatas: [tableMetadata]?) {
154-
guard let metadatas = metadatas else {
155-
uploadStarted = false
156-
uploadMetadata.removeAll()
157-
return
158-
}
159-
160-
self.uploadMetadata.append(contentsOf: metadatas)
161-
self.upload()
144+
present(alert, animated: true)
162145
}
163146
}

Share/NCShareExtension.swift

+7
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,12 @@ extension NCShareExtension {
298298

299299
var conflicts: [tableMetadata] = []
300300
for fileName in filesName {
301+
if let fileNameError = FileNameValidator.shared.checkFileName(fileName) {
302+
present(UIAlertController.warning(message: "\(fileNameError.errorDescription) \(NSLocalizedString("_please_rename_file_", comment: ""))"), animated: true)
303+
304+
continue
305+
}
306+
301307
let ocId = NSUUID().uuidString
302308
let toPath = utilityFileSystem.getDirectoryProviderStorageOcId(ocId, fileNameView: fileName)
303309
guard utilityFileSystem.copyFile(atPath: (NSTemporaryDirectory() + fileName), toPath: toPath) else { continue }
@@ -335,6 +341,7 @@ extension NCShareExtension {
335341
guard uploadStarted else { return }
336342
guard uploadMetadata.count > counterUploaded else { return DispatchQueue.main.async { self.finishedUploading() } }
337343
let metadata = uploadMetadata[counterUploaded]
344+
338345
let results = NextcloudKit.shared.nkCommonInstance.getInternalType(fileName: metadata.fileNameView, mimeType: metadata.contentType, directory: false)
339346
metadata.contentType = results.mimeType
340347
metadata.iconName = results.iconName

0 commit comments

Comments
 (0)