Try migrating old auth to keychain

This commit is contained in:
Marcus Kida 2023-06-05 15:53:27 +02:00 committed by Nathan Mattes
parent 4c9c34b6ce
commit 55afa02b52
5 changed files with 54 additions and 25 deletions

View File

@ -18,7 +18,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
let appContext = AppContext() let appContext = AppContext()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
AuthenticationServiceProvider.shared.migrateLegacyAuthenticationsIfRequired(in: appContext.managedObjectContext)
AuthenticationServiceProvider.shared.restore() AuthenticationServiceProvider.shared.restore()
AppSecret.default.register() AppSecret.default.register()

View File

@ -17,7 +17,7 @@ final class SendPostIntentHandler: NSObject {
var disposeBag = Set<AnyCancellable>() var disposeBag = Set<AnyCancellable>()
let coreDataStack = CoreDataStack() let coreDataStack = CoreDataStack(isInMemory: true)
lazy var managedObjectContext = coreDataStack.persistentContainer.viewContext lazy var managedObjectContext = coreDataStack.persistentContainer.viewContext
lazy var api: APIService = { lazy var api: APIService = {
let backgroundManagedObjectContext = coreDataStack.newTaskContext() let backgroundManagedObjectContext = coreDataStack.newTaskContext()

View File

@ -22,10 +22,15 @@ public final class CoreDataStack {
self.storeDescriptions = storeDescriptions self.storeDescriptions = storeDescriptions
} }
public convenience init(databaseName: String = "shared") { public convenience init(databaseName: String = "shared", isInMemory: Bool) {
let storeURL = URL.storeURL(for: AppName.groupID, databaseName: databaseName) let storeURL = URL.storeURL(for: AppName.groupID, databaseName: databaseName)
let storeDescription = NSPersistentStoreDescription(url: storeURL) let storeDescription: NSPersistentStoreDescription
storeDescription.url = URL(fileURLWithPath: "/dev/null") /// in-memory store with all features in favor of NSInMemoryStoreType if isInMemory {
storeDescription = NSPersistentStoreDescription(url: URL(string: "file:///dev/null")!) /// in-memory store with all features in favor of NSInMemoryStoreType
} else {
storeDescription = NSPersistentStoreDescription(url: storeURL)
storeDescription.isReadOnly = true
}
self.init(persistentStoreDescriptions: [storeDescription]) self.init(persistentStoreDescriptions: [storeDescription])
} }
@ -123,16 +128,18 @@ extension CoreDataStack {
} }
} }
extension CoreDataStack { public extension CoreDataStack {
func tearDown() {
public func rebuild() {
let oldStoreURL = persistentContainer.persistentStoreCoordinator.url(for: persistentContainer.persistentStoreCoordinator.persistentStores.first!) let oldStoreURL = persistentContainer.persistentStoreCoordinator.url(for: persistentContainer.persistentStoreCoordinator.persistentStores.first!)
try! persistentContainer.persistentStoreCoordinator.destroyPersistentStore(at: oldStoreURL, ofType: NSSQLiteStoreType, options: nil) try! persistentContainer.persistentStoreCoordinator.destroyPersistentStore(at: oldStoreURL, ofType: NSSQLiteStoreType, options: nil)
}
func rebuild() {
tearDown()
CoreDataStack.load(persistentContainer: persistentContainer) { [weak self] in CoreDataStack.load(persistentContainer: persistentContainer) { [weak self] in
guard let self = self else { return } guard let self = self else { return }
self.didFinishLoad.value = true self.didFinishLoad.value = true
} }
} }
} }

View File

@ -47,7 +47,14 @@ public class AppContext: ObservableObject {
.eraseToAnyPublisher() .eraseToAnyPublisher()
public init() { public init() {
let _coreDataStack = CoreDataStack()
/// Migrate existing Authentications to new Keychain-Based format
// var _legacyCoreDataStack: CoreDataStack? = CoreDataStack(isInMemory: false)
// AuthenticationServiceProvider.shared.migrateLegacyAuthenticationsIfRequired(in: _legacyCoreDataStack!.persistentContainer.viewContext)
// _legacyCoreDataStack!.tearDown()
// _legacyCoreDataStack = nil
let _coreDataStack = CoreDataStack(isInMemory: true)
let _managedObjectContext = _coreDataStack.persistentContainer.viewContext let _managedObjectContext = _coreDataStack.persistentContainer.viewContext
let _backgroundManagedObjectContext = _coreDataStack.persistentContainer.newBackgroundContext() let _backgroundManagedObjectContext = _coreDataStack.persistentContainer.newBackgroundContext()
coreDataStack = _coreDataStack coreDataStack = _coreDataStack

View File

@ -69,27 +69,43 @@ public extension AuthenticationServiceProvider {
} }
func migrateLegacyAuthenticationsIfRequired(in context: NSManagedObjectContext) { func migrateLegacyAuthenticationsIfRequired(in context: NSManagedObjectContext) {
guard !userDefaults.didMigrateAuthentications else { return } // guard !userDefaults.didMigrateAuthentications else { return }
defer { userDefaults.didMigrateAuthentications = true } defer { userDefaults.didMigrateAuthentications = true }
do { do {
let request = NSFetchRequest<MastodonAuthenticationLegacy>(entityName: "MastodonAuthentication") let request = NSFetchRequest<NSManagedObject>(entityName: "MastodonAuthentication")
let legacyAuthentications = try context.fetch(request) let legacyAuthentications = try context.fetch(request)
self.authentications = legacyAuthentications.map { auth in self.authentications = legacyAuthentications.compactMap { auth -> MastodonAuthentication? in
MastodonAuthentication( guard
identifier: auth.identifier, let identifier = auth.value(forKey: "identifier") as? UUID,
domain: auth.domain, let domain = auth.value(forKey: "domain") as? String,
username: auth.username, let username = auth.value(forKey: "username") as? String,
appAccessToken: auth.appAccessToken, let appAccessToken = auth.value(forKey: "appAccessToken") as? String,
userAccessToken: auth.userAccessToken, let userAccessToken = auth.value(forKey: "userAccessToken") as? String,
clientID: auth.clientID, let clientID = auth.value(forKey: "clientID") as? String,
clientSecret: auth.clientSecret, let clientSecret = auth.value(forKey: "clientSecret") as? String,
createdAt: auth.createdAt, let createdAt = auth.value(forKey: "createdAt") as? Date,
updatedAt: auth.updatedAt, let updatedAt = auth.value(forKey: "updatedAt") as? Date,
activedAt: auth.activedAt, let activedAt = auth.value(forKey: "activedAt") as? Date,
userID: auth.userID let userID = auth.value(forKey: "userID") as? String
else {
return nil
}
return MastodonAuthentication(
identifier: identifier,
domain: domain,
username: username,
appAccessToken: appAccessToken,
userAccessToken: userAccessToken,
clientID: clientID,
clientSecret: clientSecret,
createdAt: createdAt,
updatedAt: updatedAt,
activedAt: activedAt,
userID: userID
) )
} }
} catch { } catch {