Stores a deviceId inside the keychain to avoid changes

sync
Laurent 1 year ago
parent 9d3935b563
commit a978bbcbfa
  1. 19
      LeStorage/Services.swift
  2. 21
      LeStorage/StoreCenter.swift
  3. 20
      LeStorage/Utils/KeychainStore.swift

@ -209,7 +209,7 @@ public class Services {
request.httpMethod = method.rawValue
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
if !(requiresToken == false) {
let token = try self.keychainStore.getToken()
let token = try self.keychainStore.getValue()
request.addValue("Token \(token)", forHTTPHeaderField: "Authorization")
}
return request
@ -255,7 +255,7 @@ public class Services {
if self._isTokenRequired(type: T.self, method: apiCall.method) {
do {
let token = try self.keychainStore.getToken()
let token = try self.keychainStore.getValue()
request.setValue("Token \(token)", forHTTPHeaderField: "Authorization")
} catch {
Logger.log("missing token")
@ -298,7 +298,10 @@ public class Services {
/// - password: the account's password
public func requestToken(username: String, password: String) async throws -> String {
var postRequest = try self._baseRequest(conf: .requestToken)
let credentials = Credentials(username: username, password: password, deviceId: StoreCenter.main.deviceId())
let deviceId = StoreCenter.main.deviceId()
Logger.log("deviceId = \(deviceId)")
let credentials = Credentials(username: username, password: password, deviceId: deviceId)
postRequest.httpBody = try jsonEncoder.encode(credentials)
let response: AuthResponse = try await self._runRequest(postRequest)
self._storeToken(username: username, token: response.token)
@ -311,8 +314,8 @@ public class Services {
/// - token: the token to store
fileprivate func _storeToken(username: String, token: String) {
do {
try self.keychainStore.deleteToken()
try self.keychainStore.add(username: username, token: token)
try self.keychainStore.deleteValue()
try self.keychainStore.add(username: username, value: token)
} catch {
Logger.error(error)
}
@ -376,13 +379,13 @@ public class Services {
/// Deletes the locally stored token
func deleteToken() throws {
try self.keychainStore.deleteToken()
try self.keychainStore.deleteValue()
}
/// Returns whether the Service has an associated token
public func hasToken() -> Bool {
do {
_ = try self.keychainStore.getToken()
_ = try self.keychainStore.getValue()
return true
} catch {
return false
@ -412,7 +415,7 @@ public class Services {
}
func migrateToken(_ services: Services, userName: String) throws {
try self._storeToken(username: userName, token: services.keychainStore.getToken())
try self._storeToken(username: userName, token: services.keychainStore.getValue())
}
}

@ -115,7 +115,7 @@ public class StoreCenter {
/// Returns the stored token
public func token() -> String? {
return try? self.service().keychainStore.getToken()
return try? self.service().keychainStore.getValue()
}
/// Disconnect the user from the storage and resets collection
@ -133,7 +133,7 @@ public class StoreCenter {
/// Returns whether the system has a user token
public func hasToken() -> Bool {
do {
_ = try self.service().keychainStore.getToken()
_ = try self.service().keychainStore.getValue()
return true
} catch {
return false
@ -141,12 +141,19 @@ public class StoreCenter {
}
func deviceId() -> String {
let deviceId: String = self._settingsStorage.item.deviceId ?? UIDevice.current.identifierForVendor?.uuidString ??
UUID().uuidString
self._settingsStorage.update { settings in
settings.deviceId = deviceId
let keychainStore = KeychainStore(serverId: "lestorage.main")
do {
return try keychainStore.getValue()
} catch {
let deviceId: String = UIDevice.current.identifierForVendor?.uuidString ??
UUID().uuidString
do {
try keychainStore.add(value: deviceId)
} catch {
Logger.error(error)
}
return deviceId
}
return deviceId
}
// MARK: - Api Calls

@ -21,18 +21,28 @@ class KeychainStore {
self.serverId = serverId
}
func add(username: String, token: String) throws {
let tokenData = token.data(using: .utf8)!
func add(username: String, value: String) throws {
let valueData = value.data(using: .utf8)!
let query: [String: Any] = [kSecClass as String: kSecClassInternetPassword,
kSecAttrAccount as String: username,
kSecAttrServer as String: self.serverId,
kSecValueData as String: tokenData]
kSecValueData as String: valueData]
let status: OSStatus = SecItemAdd(query as CFDictionary, nil)
guard status == errSecSuccess else { throw KeychainError.unhandledError(status: status) }
}
func getToken() throws -> String {
func add(value: String) throws {
let valueData = value.data(using: .utf8)!
let query: [String: Any] = [kSecClass as String: kSecClassInternetPassword,
kSecAttrServer as String: self.serverId,
kSecValueData as String: valueData]
let status: OSStatus = SecItemAdd(query as CFDictionary, nil)
guard status == errSecSuccess else { throw KeychainError.unhandledError(status: status) }
}
func getValue() throws -> String {
let query: [String: Any] = [kSecClass as String: kSecClassInternetPassword,
kSecAttrServer as String: self.serverId,
@ -53,7 +63,7 @@ class KeychainStore {
return token
}
func deleteToken() throws {
func deleteValue() throws {
let query: [String: Any] = [kSecClass as String: kSecClassInternetPassword,
kSecAttrServer as String: self.serverId]

Loading…
Cancel
Save