]> git.saurik.com Git - apple/security.git/blame - keychain/ckks/CKKSAccountStateTracker.h
Security-59306.41.2.tar.gz
[apple/security.git] / keychain / ckks / CKKSAccountStateTracker.h
CommitLineData
866f8763
A
1/*
2 * Copyright (c) 2017 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24#import <Foundation/Foundation.h>
25
26#if OCTAGON
866f8763 27#import <CloudKit/CKContainer_Private.h>
3f0f0d49 28#import <CloudKit/CloudKit.h>
866f8763 29#include <Security/SecureObjectSync/SOSCloudCircle.h>
3f0f0d49
A
30#import "keychain/ckks/CKKSCondition.h"
31#import "keychain/ckks/CloudKitDependencies.h"
b54c578e 32#import "keychain/ot/OTClique.h"
3f0f0d49
A
33
34NS_ASSUME_NONNULL_BEGIN
866f8763
A
35
36/*
37 * Implements a 'debouncer' to store the current CK account and circle state, and receive updates to it.
38 *
b54c578e
A
39 * You can register for CK account changes, SOS account changes, or to be informed only when both are in
40 * a valid state.
866f8763
A
41 *
42 * It will notify listeners on account state changes, so multiple repeated account state notifications with the same state are filtered by this class.
43 * Listeners can also get the 'current' state, no matter what it is. They will also then be atomically added to the notification queue, and so will
44 * always receive the next update, preventing them from getting a stale state and missing an immediate update.
45 */
46
b54c578e 47// This enum represents the combined states of a CK account and the SOS account
866f8763
A
48typedef NS_ENUM(NSInteger, CKKSAccountStatus) {
49 /* Set at initialization. This means we haven't figured out what the account state is. */
3f0f0d49 50 CKKSAccountStatusUnknown = 0,
866f8763 51 /* We have an iCloud account and are in-circle */
3f0f0d49 52 CKKSAccountStatusAvailable = 1,
866f8763 53 /* No iCloud account is logged in on this device, or we're out of circle */
3f0f0d49 54 CKKSAccountStatusNoAccount = 3,
866f8763 55};
b54c578e 56NSString* CKKSAccountStatusToString(CKKSAccountStatus status);
866f8763 57
79b9da22
A
58@interface SOSAccountStatus : NSObject
59@property SOSCCStatus status;
60@property (nullable) NSError* error;
61- (instancetype)init:(SOSCCStatus)status error:error;
62@end
63
84aacf34
A
64@interface OTCliqueStatusWrapper : NSObject
65@property (readonly) CliqueStatus status;
66- (instancetype)initWithStatus:(CliqueStatus)status;
67@end
68
b54c578e
A
69@protocol CKKSOctagonStatusMemoizer
70- (void)triggerOctagonStatusFetch;
71
72@property (readonly, nullable) OTCliqueStatusWrapper* octagonStatus;
73@property (readonly, nullable) NSString* octagonPeerID;
74
75// A little bit of a abstraction violation, but it'll do.
76- (void)setHSA2iCloudAccountStatus:(CKKSAccountStatus)status;
77@end
78
79#pragma mark -- Listener Protocols
84aacf34 80
b54c578e
A
81@protocol CKKSCloudKitAccountStateListener <NSObject>
82- (void)cloudkitAccountStateChange:(CKAccountInfo* _Nullable)oldAccountInfo to:(CKAccountInfo*)currentAccountInfo;
83@end
84@protocol CKKSCloudKitAccountStateTrackingProvider <NSObject>
85- (dispatch_semaphore_t)registerForNotificationsOfCloudKitAccountStatusChange:(id<CKKSCloudKitAccountStateListener>)listener;
866f8763
A
86@end
87
b54c578e
A
88#pragma mark -- Tracker
89
90@interface CKKSAccountStateTracker : NSObject <CKKSCloudKitAccountStateTrackingProvider,
91 CKKSOctagonStatusMemoizer>
3f0f0d49 92@property CKKSCondition* finishedInitialDispatches;
866f8763
A
93
94// If you use these, please be aware they could change out from under you at any time
3f0f0d49 95@property (nullable) CKAccountInfo* currentCKAccountInfo;
b54c578e 96@property CKKSCondition* ckAccountInfoInitialized;
866f8763 97
ecaf5866 98
866f8763 99// Fetched and memoized from CloudKit; we can't afford deadlocks with their callbacks
3f0f0d49
A
100@property (nullable, copy) NSString* ckdeviceID;
101@property (nullable) NSError* ckdeviceIDError;
102@property CKKSCondition* ckdeviceIDInitialized;
866f8763 103
b54c578e
A
104// Fetched and memoized from SOS. Not otherwise used.
105@property (nullable) SOSAccountStatus* currentCircleStatus;
3f0f0d49
A
106@property (nullable) NSString* accountCirclePeerID;
107@property (nullable) NSError* accountCirclePeerIDError;
866f8763
A
108@property CKKSCondition* accountCirclePeerIDInitialized;
109
b54c578e
A
110// Filled and memoized for quick reference. Don't use for anything vital.
111// This will only fetch the status for the default context.
112@property (readonly, nullable) OTCliqueStatusWrapper* octagonStatus;
113@property (readonly, nullable) NSString* octagonPeerID;
114@property (readonly) CKKSCondition* octagonInformationInitialized;
115
116// Filled by Octagon, as it's fairly hard to compute.
117@property (readonly) CKKSAccountStatus hsa2iCloudAccountStatus;
118@property (readonly) CKKSCondition* hsa2iCloudAccountInitialized;
119
3f0f0d49 120- (instancetype)init:(CKContainer*)container nsnotificationCenterClass:(Class<CKKSNSNotificationCenter>)nsnotificationCenterClass;
866f8763 121
b54c578e
A
122- (dispatch_semaphore_t)registerForNotificationsOfCloudKitAccountStatusChange:(id<CKKSCloudKitAccountStateListener>)listener;
123
124// Call this to refetch the Octagon status
125- (void)triggerOctagonStatusFetch;
866f8763
A
126
127// Methods useful for testing:
b54c578e 128- (void)performInitialDispatches;
866f8763
A
129
130// Call this to simulate a notification (and pause the calling thread until all notifications are delivered)
3f0f0d49
A
131- (void)notifyCKAccountStatusChangeAndWaitForSignal;
132- (void)notifyCircleStatusChangeAndWaitForSignal;
133
134- (dispatch_group_t _Nullable)checkForAllDeliveries;
866f8763 135
b54c578e
A
136- (void)setHSA2iCloudAccountStatus:(CKKSAccountStatus)status;
137
79b9da22 138+ (SOSAccountStatus*)getCircleStatus;
3f0f0d49
A
139+ (void)fetchCirclePeerID:(void (^)(NSString* _Nullable peerID, NSError* _Nullable error))callback;
140+ (NSString*)stringFromAccountStatus:(CKKSAccountStatus)status;
866f8763
A
141
142@end
143
3f0f0d49
A
144NS_ASSUME_NONNULL_END
145#endif // OCTAGON