CKKSLocalResetOperation.m   [plain text]

#if OCTAGON

#import "keychain/categories/NSError+UsefulConstructors.h"
#import "keychain/ckks/CKKSLocalResetOperation.h"
#import "keychain/ckks/CKKSZoneStateEntry.h"
#import "keychain/ckks/CKKSOutgoingQueueEntry.h"
#import "keychain/ckks/CKKSIncomingQueueEntry.h"
#import "keychain/ckks/CKKSCurrentItemPointer.h"
#import "keychain/ckks/CKKSMirrorEntry.h"
#import "keychain/ot/OTDefines.h"

@implementation CKKSLocalResetOperation

@synthesize nextState = _nextState;
@synthesize intendedState = _intendedState;

- (instancetype)initWithDependencies:(CKKSOperationDependencies*)dependencies
intendedState:(OctagonState*)intendedState
errorState:(OctagonState*)errorState
{
if(self = [super init]) {
_deps = dependencies;

_intendedState = intendedState;
_nextState = errorState;

self.name = @"ckks-local-reset";
}
return self;
}

- (void)main {
[self.deps.databaseProvider dispatchSyncWithSQLTransaction:^CKKSDatabaseTransactionResult {
[self onqueuePerformLocalReset];
return CKKSDatabaseTransactionCommit;
}];
}

- (void)onqueuePerformLocalReset
{
NSError* localerror = nil;

for(CKKSKeychainViewState* view in self.deps.zones) {
CKKSZoneStateEntry* ckse = [CKKSZoneStateEntry state:view.zoneID.zoneName];
ckse.ckzonecreated = false;
ckse.ckzonesubscribed = false; // I'm actually not sure about this: can you be subscribed to a non-existent zone?
ckse.changeToken = NULL;
[ckse saveToDatabase:&localerror];
if(localerror && self.error == nil) {
ckkserror("local-reset", view.zoneID, "couldn't reset zone status: %@", localerror);
self.error = localerror;
localerror = nil;
}

[CKKSMirrorEntry deleteAll:view.zoneID error:&localerror];
if(localerror && self.error == nil) {
ckkserror("local-reset", view.zoneID, "couldn't delete all CKKSMirrorEntry: %@", localerror);
self.error = localerror;
localerror = nil;
}

[CKKSOutgoingQueueEntry deleteAll:view.zoneID error:&localerror];
if(localerror && self.error == nil) {
ckkserror("local-reset", view.zoneID, "couldn't delete all CKKSOutgoingQueueEntry: %@", localerror);
self.error = localerror;
localerror = nil;
}

[CKKSIncomingQueueEntry deleteAll:view.zoneID error:&localerror];
if(localerror && self.error == nil) {
ckkserror("local-reset", view.zoneID, "couldn't delete all CKKSIncomingQueueEntry: %@", localerror);
self.error = localerror;
localerror = nil;
}

[CKKSKey deleteAll:view.zoneID error:&localerror];
if(localerror && self.error == nil) {
ckkserror("local-reset", view.zoneID, "couldn't delete all CKKSKey: %@", localerror);
self.error = localerror;
localerror = nil;
}

[CKKSTLKShareRecord deleteAll:view.zoneID error:&localerror];
if(localerror && self.error == nil) {
ckkserror("local-reset", view.zoneID, "couldn't delete all CKKSTLKShare: %@", localerror);
self.error = localerror;
localerror = nil;
}

[CKKSCurrentKeyPointer deleteAll:view.zoneID error:&localerror];
if(localerror && self.error == nil) {
ckkserror("local-reset", view.zoneID, "couldn't delete all CKKSCurrentKeyPointer: %@", localerror);
self.error = localerror;
localerror = nil;
}

[CKKSCurrentItemPointer deleteAll:view.zoneID error:&localerror];
if(localerror && self.error == nil) {
ckkserror("local-reset", view.zoneID, "couldn't delete all CKKSCurrentItemPointer: %@", localerror);
self.error = localerror;
localerror = nil;
}

[CKKSDeviceStateEntry deleteAll:view.zoneID error:&localerror];
if(localerror && self.error == nil) {
ckkserror("local-reset", view.zoneID, "couldn't delete all CKKSDeviceStateEntry: %@", localerror);
self.error = localerror;
localerror = nil;
}

if(self.error) {
break;
}
}

if(!self.error) {
ckksnotice_global("local-reset", "Successfully deleted all local data for zones: %@", self.deps.zones);
self.nextState = self.intendedState;
}
}

@end

#endif // OCTAGON