Polish folder related methods
This commit is contained in:
parent
a499be7628
commit
dd254b21d9
4 changed files with 66 additions and 39 deletions
|
|
@ -25,7 +25,8 @@ class EditPasswordTableViewController: PasswordEditorTableViewController {
|
||||||
if identifier == "saveEditPasswordSegue" {
|
if identifier == "saveEditPasswordSegue" {
|
||||||
if let nameCell = tableView.cellForRow(at: IndexPath(row: 0, section: 0)) as? ContentTableViewCell {
|
if let nameCell = tableView.cellForRow(at: IndexPath(row: 0, section: 0)) as? ContentTableViewCell {
|
||||||
if let name = nameCell.getContent(),
|
if let name = nameCell.getContent(),
|
||||||
let _ = URL(string: name) {
|
let path = name.stringByAddingPercentEncodingForRFC3986(),
|
||||||
|
let _ = URL(string: path) {
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
Utils.alert(title: "Cannot Save", message: "Password name is invalid.", controller: self, completion: nil)
|
Utils.alert(title: "Cannot Save", message: "Password name is invalid.", controller: self, completion: nil)
|
||||||
|
|
@ -55,8 +56,8 @@ class EditPasswordTableViewController: PasswordEditorTableViewController {
|
||||||
} else {
|
} else {
|
||||||
plainText = "\(cellContents["password"]!)"
|
plainText = "\(cellContents["password"]!)"
|
||||||
}
|
}
|
||||||
let name = URL(string: cellContents["name"]!)!.lastPathComponent
|
let name = URL(string: cellContents["name"]!.stringByAddingPercentEncodingForRFC3986()!)!.lastPathComponent
|
||||||
let url = URL(string: cellContents["name"]!)!.appendingPathExtension("gpg")
|
let url = URL(string: cellContents["name"]!.stringByAddingPercentEncodingForRFC3986()!)!.appendingPathExtension("gpg")
|
||||||
if password!.plainText != plainText || password!.url!.path != url.path {
|
if password!.plainText != plainText || password!.url!.path != url.path {
|
||||||
password!.updatePassword(name: name, url: url, plainText: plainText)
|
password!.updatePassword(name: name, url: url, plainText: plainText)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -238,3 +238,12 @@ extension FileManager {
|
||||||
return accumulatedSize
|
return accumulatedSize
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension String {
|
||||||
|
func stringByAddingPercentEncodingForRFC3986() -> String? {
|
||||||
|
let unreserved = "-._~/?"
|
||||||
|
var allowed = CharacterSet.alphanumerics
|
||||||
|
allowed.insert(charactersIn: unreserved)
|
||||||
|
return addingPercentEncoding(withAllowedCharacters: allowed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ extension PasswordEntity {
|
||||||
|
|
||||||
func getURL() -> URL? {
|
func getURL() -> URL? {
|
||||||
if let p = path {
|
if let p = path {
|
||||||
return URL(string: p)
|
return URL(string: p.stringByAddingPercentEncodingForRFC3986()!)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -518,24 +518,35 @@ class PasswordStore {
|
||||||
|
|
||||||
private func gitRm(path: String) throws {
|
private func gitRm(path: String) throws {
|
||||||
if let repo = storeRepository {
|
if let repo = storeRepository {
|
||||||
var url = storeURL.appendingPathComponent(path)
|
|
||||||
Utils.removeFileIfExists(at: url)
|
|
||||||
let fm = FileManager.default
|
|
||||||
url.deleteLastPathComponent()
|
|
||||||
var count = try fm.contentsOfDirectory(atPath: url.path).count
|
|
||||||
while count == 0 {
|
|
||||||
Utils.removeFileIfExists(atPath: url.path)
|
|
||||||
url.deleteLastPathComponent()
|
|
||||||
count = try fm.contentsOfDirectory(atPath: url.path).count
|
|
||||||
}
|
|
||||||
try repo.index().removeFile(path)
|
try repo.index().removeFile(path)
|
||||||
try repo.index().write()
|
try repo.index().write()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private func deleteDirectoryTree(at url: URL) throws {
|
||||||
|
var tempURL = storeURL.appendingPathComponent(url.deletingLastPathComponent().path)
|
||||||
|
let fm = FileManager.default
|
||||||
|
var count = try fm.contentsOfDirectory(atPath: tempURL.path).count
|
||||||
|
while count == 0 {
|
||||||
|
try fm.removeItem(at: tempURL)
|
||||||
|
tempURL.deleteLastPathComponent()
|
||||||
|
count = try fm.contentsOfDirectory(atPath: tempURL.path).count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func createDirectoryTree(at url: URL) throws {
|
||||||
|
let tempURL = storeURL.appendingPathComponent(url.deletingLastPathComponent().path)
|
||||||
|
try FileManager.default.createDirectory(at: tempURL, withIntermediateDirectories: true, attributes: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func gitMv(from: String, to: String) throws {
|
private func gitMv(from: String, to: String) throws {
|
||||||
let fm = FileManager.default
|
let fm = FileManager.default
|
||||||
do {
|
do {
|
||||||
|
guard fm.fileExists(atPath: storeURL.appendingPathComponent(from).path) else {
|
||||||
|
print("\(from) not exist")
|
||||||
|
return
|
||||||
|
}
|
||||||
try fm.moveItem(at: storeURL.appendingPathComponent(from), to: storeURL.appendingPathComponent(to))
|
try fm.moveItem(at: storeURL.appendingPathComponent(from), to: storeURL.appendingPathComponent(to))
|
||||||
} catch {
|
} catch {
|
||||||
print(error)
|
print(error)
|
||||||
|
|
@ -597,16 +608,9 @@ class PasswordStore {
|
||||||
parentPasswordEntity = passwordEntity
|
parentPasswordEntity = passwordEntity
|
||||||
} else {
|
} else {
|
||||||
if path.hasSuffix(".gpg") {
|
if path.hasSuffix(".gpg") {
|
||||||
return insertPasswordEntity(name: URL(string: path)!.deletingPathExtension().lastPathComponent, path: path, parent: parentPasswordEntity, synced: false, isDir: false)
|
return insertPasswordEntity(name: URL(string: path.stringByAddingPercentEncodingForRFC3986()!)!.deletingPathExtension().lastPathComponent, path: path, parent: parentPasswordEntity, synced: false, isDir: false)
|
||||||
} else {
|
} else {
|
||||||
parentPasswordEntity = insertPasswordEntity(name: URL(string: path)!.lastPathComponent, path: path, parent: parentPasswordEntity, synced: false, isDir: true)
|
parentPasswordEntity = insertPasswordEntity(name: URL(string: path.stringByAddingPercentEncodingForRFC3986()!)!.lastPathComponent, path: path, parent: parentPasswordEntity, synced: false, isDir: true)
|
||||||
let fm = FileManager.default
|
|
||||||
let saveURL = storeURL.appendingPathComponent(path)
|
|
||||||
do {
|
|
||||||
try fm.createDirectory(at: saveURL, withIntermediateDirectories: false, attributes: nil)
|
|
||||||
} catch {
|
|
||||||
print(error)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -632,6 +636,7 @@ class PasswordStore {
|
||||||
}
|
}
|
||||||
|
|
||||||
func add(password: Password) throws -> PasswordEntity? {
|
func add(password: Password) throws -> PasswordEntity? {
|
||||||
|
try createDirectoryTree(at: password.url!)
|
||||||
let newPasswordEntity = try addPasswordEntities(password: password)
|
let newPasswordEntity = try addPasswordEntities(password: password)
|
||||||
let saveURL = storeURL.appendingPathComponent(password.url!.path)
|
let saveURL = storeURL.appendingPathComponent(password.url!.path)
|
||||||
try self.encrypt(password: password).write(to: saveURL)
|
try self.encrypt(password: password).write(to: saveURL)
|
||||||
|
|
@ -641,24 +646,42 @@ class PasswordStore {
|
||||||
return newPasswordEntity
|
return newPasswordEntity
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func delete(passwordEntity: PasswordEntity) throws {
|
||||||
|
let deletedFileURL = passwordEntity.getURL()!
|
||||||
|
try deleteDirectoryTree(at: passwordEntity.getURL()!)
|
||||||
|
try deletePasswordEntities(passwordEntity: passwordEntity)
|
||||||
|
try gitRm(path: deletedFileURL.path)
|
||||||
|
let _ = try gitCommit(message: "Remove \(deletedFileURL.deletingPathExtension()) from store using Pass for iOS.")
|
||||||
|
NotificationCenter.default.post(name: .passwordStoreUpdated, object: nil)
|
||||||
|
}
|
||||||
|
|
||||||
func edit(passwordEntity: PasswordEntity, password: Password) throws -> PasswordEntity? {
|
func edit(passwordEntity: PasswordEntity, password: Password) throws -> PasswordEntity? {
|
||||||
var newPasswordEntity: PasswordEntity? = passwordEntity
|
var newPasswordEntity: PasswordEntity? = passwordEntity
|
||||||
|
|
||||||
if password.changed&PasswordChange.content.rawValue != 0 {
|
if password.changed&PasswordChange.content.rawValue != 0 {
|
||||||
|
print("chagne content")
|
||||||
let saveURL = storeURL.appendingPathComponent(passwordEntity.getURL()!.path)
|
let saveURL = storeURL.appendingPathComponent(passwordEntity.getURL()!.path)
|
||||||
try self.encrypt(password: password).write(to: saveURL)
|
try self.encrypt(password: password).write(to: saveURL)
|
||||||
try gitAdd(path: passwordEntity.getURL()!.path)
|
try gitAdd(path: passwordEntity.getURL()!.path)
|
||||||
let _ = try gitCommit(message: "Edit password for \(passwordEntity.getURL()!.deletingPathExtension().path) to store using Pass for iOS.")
|
let _ = try gitCommit(message: "Edit password for \(passwordEntity.getURL()!.deletingPathExtension().path) to store using Pass for iOS.")
|
||||||
|
newPasswordEntity = passwordEntity
|
||||||
}
|
}
|
||||||
guard newPasswordEntity != nil else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
if password.changed&PasswordChange.path.rawValue != 0 {
|
if password.changed&PasswordChange.path.rawValue != 0 {
|
||||||
let oldPasswordURL = newPasswordEntity!.getURL()
|
print("change path")
|
||||||
try self.deletePasswordEntities(passwordEntity: newPasswordEntity!)
|
let deletedFileURL = passwordEntity.getURL()!
|
||||||
newPasswordEntity = try self.addPasswordEntities(password: password)
|
// add
|
||||||
try gitMv(from: oldPasswordURL!.path, to: password.url!.path)
|
try createDirectoryTree(at: password.url!)
|
||||||
let _ = try gitCommit(message: "Rename \(oldPasswordURL!.deletingPathExtension().path) to \(password.url!.deletingPathExtension().path) using Pass for iOS.")
|
newPasswordEntity = try addPasswordEntities(password: password)
|
||||||
|
|
||||||
|
// mv
|
||||||
|
try gitMv(from: deletedFileURL.path, to: password.url!.path)
|
||||||
|
|
||||||
|
// delete
|
||||||
|
try deleteDirectoryTree(at: deletedFileURL)
|
||||||
|
try deletePasswordEntities(passwordEntity: passwordEntity)
|
||||||
|
let _ = try gitCommit(message: "Rename \(deletedFileURL.deletingPathExtension()) to \(password.url!.deletingPathExtension().path) using Pass for iOS.")
|
||||||
|
|
||||||
}
|
}
|
||||||
NotificationCenter.default.post(name: .passwordStoreUpdated, object: nil)
|
NotificationCenter.default.post(name: .passwordStoreUpdated, object: nil)
|
||||||
return newPasswordEntity
|
return newPasswordEntity
|
||||||
|
|
@ -678,13 +701,6 @@ class PasswordStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func delete(passwordEntity: PasswordEntity) throws {
|
|
||||||
try gitRm(path: passwordEntity.path!)
|
|
||||||
let _ = try gitCommit(message: "Remove \(passwordEntity.nameWithCategory) from store using Pass for iOS.")
|
|
||||||
try deletePasswordEntities(passwordEntity: passwordEntity)
|
|
||||||
NotificationCenter.default.post(name: .passwordStoreUpdated, object: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func saveUpdated(passwordEntity: PasswordEntity) {
|
func saveUpdated(passwordEntity: PasswordEntity) {
|
||||||
do {
|
do {
|
||||||
try context.save()
|
try context.save()
|
||||||
|
|
@ -815,7 +831,8 @@ class PasswordStore {
|
||||||
}
|
}
|
||||||
let decryptedData = try PasswordStore.shared.pgp.decryptData(encryptedData, passphrase: passphrase)
|
let decryptedData = try PasswordStore.shared.pgp.decryptData(encryptedData, passphrase: passphrase)
|
||||||
let plainText = String(data: decryptedData, encoding: .utf8) ?? ""
|
let plainText = String(data: decryptedData, encoding: .utf8) ?? ""
|
||||||
password = Password(name: passwordEntity.name!, url: URL(string: passwordEntity.path!), plainText: plainText)
|
let escapedPath = passwordEntity.path!.stringByAddingPercentEncodingForRFC3986() ?? ""
|
||||||
|
password = Password(name: passwordEntity.name!, url: URL(string: escapedPath), plainText: plainText)
|
||||||
return password
|
return password
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue