Proyectos de Subversion Iphone Microlearning

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
/*
2
 * Copyright 2019 Google
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
 
17
#import "FirebaseMessaging/Sources/Token/FIRMessagingCheckinStore.h"
18
 
19
#import "FirebaseMessaging/Sources/FIRMessagingCode.h"
20
#import "FirebaseMessaging/Sources/FIRMessagingConstants.h"
21
#import "FirebaseMessaging/Sources/FIRMessagingLogger.h"
22
#import "FirebaseMessaging/Sources/FIRMessagingUtilities.h"
23
#import "FirebaseMessaging/Sources/NSError+FIRMessaging.h"
24
#import "FirebaseMessaging/Sources/Token/FIRMessagingAuthKeychain.h"
25
#import "FirebaseMessaging/Sources/Token/FIRMessagingBackupExcludedPlist.h"
26
#import "FirebaseMessaging/Sources/Token/FIRMessagingCheckinPreferences.h"
27
#import "FirebaseMessaging/Sources/Token/FIRMessagingCheckinService.h"
28
 
29
// NOTE: These values should be in sync with what InstanceID saves in as.
30
static NSString *const kCheckinFileName = @"g-checkin";
31
static NSString *const kFIRMessagingCheckinKeychainGeneric = @"com.google.iid";
32
NSString *const kFIRMessagingCheckinKeychainService = @"com.google.iid.checkin";
33
 
34
@interface FIRMessagingCheckinStore ()
35
 
36
@property(nonatomic, readwrite, strong) FIRMessagingBackupExcludedPlist *plist;
37
@property(nonatomic, readwrite, strong) FIRMessagingAuthKeychain *keychain;
38
// Checkin will store items under
39
// Keychain account: <app bundle id>,
40
// Keychain service: |kFIRMessagingCheckinKeychainService|
41
@property(nonatomic, readonly) NSString *bundleIdentifierForKeychainAccount;
42
 
43
@end
44
 
45
@implementation FIRMessagingCheckinStore
46
 
47
- (instancetype)init {
48
  self = [super init];
49
  if (self) {
50
    _plist = [[FIRMessagingBackupExcludedPlist alloc]
51
        initWithFileName:kCheckinFileName
52
            subDirectory:kFIRMessagingInstanceIDSubDirectoryName];
53
    _keychain =
54
        [[FIRMessagingAuthKeychain alloc] initWithIdentifier:kFIRMessagingCheckinKeychainGeneric];
55
  }
56
  return self;
57
}
58
 
59
- (BOOL)hasCheckinPlist {
60
  return [self.plist doesFileExist];
61
}
62
 
63
- (NSString *)bundleIdentifierForKeychainAccount {
64
  static NSString *bundleIdentifier;
65
  static dispatch_once_t onceToken;
66
  dispatch_once(&onceToken, ^{
67
    bundleIdentifier = FIRMessagingAppIdentifier();
68
  });
69
  return bundleIdentifier;
70
}
71
 
72
- (void)saveCheckinPreferences:(FIRMessagingCheckinPreferences *)preferences
73
                       handler:(void (^)(NSError *error))handler {
74
  NSDictionary *checkinPlistContents = [preferences checkinPlistContents];
75
  NSString *checkinKeychainContent = [preferences checkinKeychainContent];
76
 
77
  if (![checkinKeychainContent length]) {
78
    NSString *failureReason = @"Failed to get checkin keychain content from memory.";
79
    FIRMessagingLoggerDebug(kFIRMessagingMessageCodeCheckinStore000, @"%@", failureReason);
80
    if (handler) {
81
      handler([NSError messagingErrorWithCode:kFIRMessagingErrorCodeRegistrarFailedToCheckIn
82
                                failureReason:failureReason]);
83
    }
84
    return;
85
  }
86
  if (![checkinPlistContents count]) {
87
    NSString *failureReason = @"Failed to get checkin plist contents from memory.";
88
    FIRMessagingLoggerDebug(kFIRMessagingMessageCodeCheckinStore001, @"%@", failureReason);
89
    if (handler) {
90
      handler([NSError messagingErrorWithCode:kFIRMessagingErrorCodeRegistrarFailedToCheckIn
91
                                failureReason:failureReason]);
92
    }
93
    return;
94
  }
95
 
96
  // Save all other checkin preferences in a plist
97
  NSError *error;
98
  if (![self.plist writeDictionary:checkinPlistContents error:&error]) {
99
    FIRMessagingLoggerDebug(kFIRMessagingMessageCodeCheckinStore003,
100
                            @"Failed to save checkin plist contents."
101
                            @"Will delete auth credentials");
102
    [self.keychain removeItemsMatchingService:kFIRMessagingCheckinKeychainService
103
                                      account:self.bundleIdentifierForKeychainAccount
104
                                      handler:nil];
105
    if (handler) {
106
      handler(error);
107
    }
108
    return;
109
  }
110
  FIRMessagingLoggerDebug(kFIRMessagingMessageCodeCheckinStoreCheckinPlistSaved,
111
                          @"Checkin plist file is saved");
112
 
113
  // Save the deviceID and secret in the Keychain
114
  if (!preferences.hasPreCachedAuthCredentials) {
115
    NSData *data = [checkinKeychainContent dataUsingEncoding:NSUTF8StringEncoding];
116
    [self.keychain setData:data
117
                forService:kFIRMessagingCheckinKeychainService
118
                   account:self.bundleIdentifierForKeychainAccount
119
                   handler:^(NSError *error) {
120
                     if (error) {
121
                       if (handler) {
122
                         handler(error);
123
                       }
124
                       return;
125
                     }
126
                     if (handler) {
127
                       handler(nil);
128
                     }
129
                   }];
130
  } else {
131
    handler(nil);
132
  }
133
}
134
 
135
- (void)removeCheckinPreferencesWithHandler:(void (^)(NSError *error))handler {
136
  // Delete the checkin preferences plist first to avoid delay.
137
  NSError *deletePlistError;
138
  if (![self.plist deleteFile:&deletePlistError]) {
139
    handler(deletePlistError);
140
    return;
141
  }
142
  FIRMessagingLoggerDebug(kFIRMessagingMessageCodeCheckinStoreCheckinPlistDeleted,
143
                          @"Deleted checkin plist file.");
144
  // Remove deviceID and secret from Keychain
145
  [self.keychain removeItemsMatchingService:kFIRMessagingCheckinKeychainService
146
                                    account:self.bundleIdentifierForKeychainAccount
147
                                    handler:^(NSError *error) {
148
                                      handler(error);
149
                                    }];
150
}
151
 
152
- (FIRMessagingCheckinPreferences *)cachedCheckinPreferences {
153
  // Query the keychain for deviceID and secret
154
  NSData *item = [self.keychain dataForService:kFIRMessagingCheckinKeychainService
155
                                       account:self.bundleIdentifierForKeychainAccount];
156
 
157
  // Check info found in keychain
158
  NSString *checkinKeychainContent = [[NSString alloc] initWithData:item
159
                                                           encoding:NSUTF8StringEncoding];
160
  FIRMessagingCheckinPreferences *checkinPreferences = [FIRMessagingCheckinPreferences
161
      preferencesFromKeychainContents:[checkinKeychainContent copy]];
162
 
163
  NSDictionary *checkinPlistContents = [self.plist contentAsDictionary];
164
 
165
  NSString *plistDeviceAuthID = checkinPlistContents[kFIRMessagingDeviceAuthIdKey];
166
  NSString *plistSecretToken = checkinPlistContents[kFIRMessagingSecretTokenKey];
167
 
168
  // If deviceID and secret not found in the keychain verify that we don't have them in the
169
  // checkin preferences plist.
170
  if (![checkinPreferences.deviceID length] && ![checkinPreferences.secretToken length]) {
171
    if ([plistDeviceAuthID length] && [plistSecretToken length]) {
172
      // Couldn't find checkin credentials in keychain but found them in the plist.
173
      checkinPreferences =
174
          [[FIRMessagingCheckinPreferences alloc] initWithDeviceID:plistDeviceAuthID
175
                                                       secretToken:plistSecretToken];
176
    } else {
177
      // Couldn't find checkin credentials in keychain nor plist
178
      return nil;
179
    }
180
  }
181
 
182
  [checkinPreferences updateWithCheckinPlistContents:checkinPlistContents];
183
  return checkinPreferences;
184
}
185
 
186
@end