OTDetermineHSA2AccountStatusOperation.m   [plain text]



#if OCTAGON

#import "utilities/debugging.h"

#import "keychain/ot/OTConstants.h"
#import "keychain/ot/OTDetermineHSA2AccountStatusOperation.h"
#import "keychain/ot/OTStates.h"
#import "keychain/ckks/CKKSAccountStateTracker.h"

#import "keychain/ot/categories/OTAccountMetadataClassC+KeychainSupport.h"
#import "keychain/TrustedPeersHelper/TrustedPeersHelperProtocol.h"
#import "keychain/ot/ObjCImprovements.h"

@interface OTDetermineHSA2AccountStatusOperation ()
@property OTOperationDependencies* deps;

@property OctagonState* stateIfNotHSA2;
@property OctagonState* stateIfNoAccount;
@property NSOperation* finishedOp;
@end

@implementation OTDetermineHSA2AccountStatusOperation
@synthesize intendedState = _intendedState;

- (instancetype)initWithDependencies:(OTOperationDependencies*)dependencies
                         stateIfHSA2:(OctagonState*)stateIfHSA2
                      stateIfNotHSA2:(OctagonState*)stateIfNotHSA2
                    stateIfNoAccount:(OctagonState*)stateIfNoAccount
                          errorState:(OctagonState*)errorState
{
    if((self = [super init])) {
        _deps = dependencies;

        _intendedState = stateIfHSA2;
        _stateIfNotHSA2 = stateIfNotHSA2;
        _stateIfNoAccount = stateIfNoAccount;
        _nextState = errorState;
    }
    return self;
}

- (void)groupStart
{
    self.finishedOp = [[NSOperation alloc] init];
    [self dependOnBeforeGroupFinished:self.finishedOp];

    NSError *error = nil;
    NSString* primaryAccountAltDSID = [self.deps.authKitAdapter primaryiCloudAccountAltDSID:&error];


    if(primaryAccountAltDSID != nil) {
        secnotice("octagon", "iCloud account is present; checking HSA2 status");

        bool hsa2 = [self.deps.authKitAdapter accountIsHSA2ByAltDSID:primaryAccountAltDSID];
        secnotice("octagon", "HSA2 is %@", hsa2 ? @"enabled" : @"disabled");

        [self.deps.stateHolder persistAccountChanges:^OTAccountMetadataClassC *(OTAccountMetadataClassC * metadata) {
            if(hsa2) {
                metadata.icloudAccountState = OTAccountMetadataClassC_AccountState_ACCOUNT_AVAILABLE;
            } else {
                metadata.icloudAccountState = OTAccountMetadataClassC_AccountState_NO_ACCOUNT;
            }
            metadata.altDSID = primaryAccountAltDSID;
            return metadata;
        } error:&error];

        // If there's an HSA2 account, return to 'initializing' here, as we want to centralize decisions on what to do next
        if(hsa2) {
            self.nextState = self.intendedState;
        } else {
            //[self.deps.accountStateTracker setHSA2iCloudAccountStatus:CKKSAccountStatusNoAccount];
            self.nextState = self.stateIfNotHSA2;
        }

    } else {
        secnotice("octagon", "iCloud account is not present: %@", error);

        [self.deps.stateHolder persistAccountChanges:^OTAccountMetadataClassC *(OTAccountMetadataClassC * metadata) {
            metadata.icloudAccountState = OTAccountMetadataClassC_AccountState_NO_ACCOUNT;
            metadata.altDSID = nil;
            return metadata;
        } error:&error];

        self.nextState = self.stateIfNoAccount;
    }

    if(error) {
        secerror("octagon: unable to save new account state: %@", error);
    }

    [self runBeforeGroupFinished:self.finishedOp];
}

@end

#endif // OCTAGON