| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- // KDBX.swift
- // This file is part of KeePass.
- //
- // Copyright © 2019 Maxime Epain. All rights reserved.
- //
- // KeePass is free software: you can redistribute it and/or modify
- // it under the terms of the GNU General Public License as published by
- // the Free Software Foundation, either version 3 of the License, or
- // (at your option) any later version.
- //
- // KeePass is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- // GNU General Public License for more details.
- //
- // You should have received a copy of the GNU General Public License
- // along with KeePass. If not, see <https://www.gnu.org/licenses/>.
- import Foundation
- import Binary
- import XML
- import KDBX
- let DateFormatter = ISO8601DateFormatter()
- extension CompositeKey: KDBX.CompositeKey { }
- extension KDBX.File: Database {
- public var root: Element { database.document.root.KeePassFile.Root }
- }
- extension Element {
- private var this: XML.Element { self }
- }
- extension XML.Element {
- convenience init(_ field: Field) {
- self.init(name: field.name, value: field.value, attributes: [:])
- }
- }
- extension Field {
- init?(_ element: XML.Element) {
- guard let key = element.Key.value else { return nil }
- name = key
- value = element.Value.value
- isProtected = element.Value.attributes["Protected"] == "True"
- }
- }
- extension XML.Element: Entry {
- public var times: Timestamp { self.Times }
- public var fields: [Field] {
- allDescendants(where: { $0.name == "String" }).compactMap { Field($0) }
- }
- public func set(_ field: Field) {
- allDescendants(where: { $0.name == field.name })
- .forEach { $0.removeFromParent() }
- addChild( XML.Element(field) )
- }
- }
- extension XML.Element: Timestamp {
- public var creationDate: Date {
- self.CreationTime.date(formatter: DateFormatter) ?? .distantPast
- }
- public var lastModifiedDate: Date {
- get { self.LastModificationTime.date(formatter: DateFormatter) ?? .distantPast }
- set { self.LastModificationTime.value = DateFormatter.string(from: newValue) }
- }
- public var lastAccessDate: Date {
- get { self.LastAccessTime.date(formatter: DateFormatter) ?? .distantPast }
- set { self.LastAccessTime.value = DateFormatter.string(from: newValue) }
- }
- public var expirationDate: Date? {
- get { self.ExpiryTime.date(formatter: DateFormatter) }
- set {
- if let value = newValue {
- self.ExpiryTime.value = DateFormatter.string(from: value)
- addChild(name: "Expires", value: "True")
- } else {
- self.ExpiryTime.value = DateFormatter.string(from: Date.distantFuture)
- addChild(name: "Expires", value: "False")
- }
- }
- }
- }
- extension XML.Element: Group {
- public var title: String {
- get { attributes["Title"] ?? "" }
- set { attributes["Title"] = newValue }
- }
- public var icon: Int {
- get {
- guard let attr = attributes["Icon"], let icon = Int(attr) else { return 0 }
- return icon
- }
- set { attributes["Icon"] = "\(newValue)" }
- }
- public var entries: [Element] {
- allDescendants(where: { $0.name == "Entry" })
- }
- public var groups: [Element] {
- allDescendants(where: { $0.name == "Group" })
- }
- }
|