-
Notifications
You must be signed in to change notification settings - Fork 384
/
Copy pathIPOverrideRepository.swift
94 lines (76 loc) · 2.81 KB
/
IPOverrideRepository.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
//
// IPOverrideRepository.swift
// MullvadVPN
//
// Created by Jon Petersson on 2024-01-16.
// Copyright © 2024 Mullvad VPN AB. All rights reserved.
//
import Foundation
import MullvadLogging
public protocol IPOverrideRepositoryProtocol {
func add(_ overrides: [IPOverride])
func fetchAll() -> [IPOverride]
func deleteAll()
func parse(data: Data) throws -> [IPOverride]
}
public class IPOverrideRepository: IPOverrideRepositoryProtocol {
private let logger = Logger(label: "IPOverrideRepository")
private let readWriteLock = NSLock()
public init() {}
public func add(_ overrides: [IPOverride]) {
var storedOverrides = fetchAll()
overrides.forEach { override in
if let existingOverrideIndex = storedOverrides.firstIndex(where: { $0.hostname == override.hostname }) {
var existingOverride = storedOverrides[existingOverrideIndex]
if let ipv4Address = override.ipv4Address {
existingOverride.ipv4Address = ipv4Address
}
if let ipv6Address = override.ipv6Address {
existingOverride.ipv6Address = ipv6Address
}
storedOverrides[existingOverrideIndex] = existingOverride
} else {
storedOverrides.append(override)
}
}
do {
try writeIpOverrides(storedOverrides)
} catch {
logger.error("Could not add override(s): \(overrides) \nError: \(error)")
}
}
public func fetchAll() -> [IPOverride] {
return (try? readIpOverrides()) ?? []
}
public func deleteAll() {
do {
try readWriteLock.withLock {
try SettingsManager.store.delete(key: .ipOverrides)
}
} catch {
logger.error("Could not delete all overrides. \nError: \(error)")
}
}
public func parse(data: Data) throws -> [IPOverride] {
let decoder = JSONDecoder()
let jsonData = try decoder.decode(RelayOverrides.self, from: data)
return jsonData.overrides
}
private func readIpOverrides() throws -> [IPOverride] {
try readWriteLock.withLock {
let parser = makeParser()
let data = try SettingsManager.store.read(key: .ipOverrides)
return try parser.parseUnversionedPayload(as: [IPOverride].self, from: data)
}
}
private func writeIpOverrides(_ overrides: [IPOverride]) throws {
let parser = makeParser()
let data = try parser.produceUnversionedPayload(overrides)
try readWriteLock.withLock {
try SettingsManager.store.write(data, for: .ipOverrides)
}
}
private func makeParser() -> SettingsParser {
SettingsParser(decoder: JSONDecoder(), encoder: JSONEncoder())
}
}