721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott/*
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott * The contents of this file are subject to the terms of the Common Development and
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott * Distribution License (the License). You may not use this file except in compliance with the
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott * License.
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott *
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott * specific language governing permission and limitations under the License.
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott *
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott * When distributing Covered Software, include this CDDL Header Notice in each file and include
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott * Header, with the fields enclosed by brackets [] replaced by your own identifying
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott * information: "Portions copyright [year] [name of copyright owner]".
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott *
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott * Copyright 2016 ForgeRock AS.
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott */
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott#import "FMDatabase.h"
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott#import "FRAError.h"
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott#import "FRAFMDatabaseConnectionHelper.h"
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni#import "FRAOathCode.h"
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott#import "FRAIdentity.h"
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott#import "FRAModelObjectProtected.h"
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott#import "FRAModelsFromDatabase.h"
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott#import "FRANotification.h"
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni#import "FRAHotpOathMechanism.h"
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni#import "FRATotpOathMechanism.h"
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott#import "FRAPushMechanism.h"
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott#import "FRASerialization.h"
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott/*!
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott*/
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott@implementation FRAModelsFromDatabase
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott/*!
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott * The parsing logic operates as follows:
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott *
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott * Perform SQL query to fetch all Identities, Mechanisms and Notifications where each
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott * Identity may have multiple associated Mechanisms and PushMechanisms may have multiple
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott * associated Notifications.
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott *
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott * The function will re-use matching Identities and Push Mechanisms as appropriate.
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott *
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott * TODO: Split into smaller functions.
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott */
6a2ae9c7fb4d2c40d75cab0edaf940f22c18224fDiego Colantoni+ (NSArray<FRAIdentity*> *)allIdentitiesWithDatabase:(FRAFMDatabaseConnectionHelper *)sqlDatabase identityDatabase:(FRAIdentityDatabase *)identityDatabase identityModel:(FRAIdentityModel *)identityModel error:(NSError *__autoreleasing *)error {
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott NSString *sql = [FRAFMDatabaseConnectionHelper readSchema:@"read_all" withError:error];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott if (!sql) {
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott return nil;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott }
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott // Open Database
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott FMDatabase *database;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott @try {
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott database = [sqlDatabase getConnectionWithError:error];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott if (!database) {
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott return nil;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott }
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott // Perform update
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott FMResultSet *results = [database executeQuery:sql];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott if (!results) {
78c07714ec1113f7f21c75b818f2bf6a7021618aDiego Colantoni if (error) {
78c07714ec1113f7f21c75b818f2bf6a7021618aDiego Colantoni *error = [FRAError createErrorForLastFailure:database];
78c07714ec1113f7f21c75b818f2bf6a7021618aDiego Colantoni }
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott return nil;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott }
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott // Output rows for debugging purposes.
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott NSLog(@"Reading all rows from the database:");
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott NSMutableArray* identities = [[NSMutableArray alloc] init];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott int row = 0;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott while ([results next]) {
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott // Identity
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott NSString *issuer = [FRASerialization nullToEmpty:[results stringForColumn:@"issuer"]];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott NSString *accountName = [FRASerialization nullToEmpty:[results stringForColumn:@"accountName"]];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott NSString *imageURL = [FRASerialization nullToEmpty:[results stringForColumn:@"imageURL"]];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott NSString *bgColor = [FRASerialization nullToEmpty:[results stringForColumn:@"bgColor"]];
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott // Mechanism
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott NSString *type = [FRASerialization nullToEmpty:[results stringForColumn:@"type"]];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott NSInteger version = [results intForColumn:@"version"];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott NSString *mechanismUID = [FRASerialization nullToEmpty:[results stringForColumn:@"mechanismUID"]];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott NSString *optionsJSON = [FRASerialization nullToEmpty:[results stringForColumn:@"options"]];
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott // Notification
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott NSString *timeReceived = [FRASerialization nullToEmpty:[results stringForColumn:@"timeReceived"]];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott NSString *timeExpired = [FRASerialization nullToEmpty:[results stringForColumn:@"timeExpired"]];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott NSString *data = [FRASerialization nullToEmpty:[results stringForColumn:@"data"]];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott int pending = [results intForColumn:@"pending"];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott int approved = [results intForColumn:@"approved"];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott NSLog(@"[%d] %@ %@ %@ %@ %@ %ld %@ %@ %@ %d %d",
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott row,
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott issuer,
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott accountName,
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott imageURL,
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott bgColor,
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott type,
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott (long)version,
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott mechanismUID,
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott timeReceived,
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott timeExpired,
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott pending,
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott approved);
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott row++;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott // Create an Identity
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott FRAIdentity* newIdentity = [FRAIdentity
f877f6ca2428244a6d0954a1dbef471577b32c60Diego Colantoni identityWithDatabase:identityDatabase
f877f6ca2428244a6d0954a1dbef471577b32c60Diego Colantoni identityModel:identityModel
f877f6ca2428244a6d0954a1dbef471577b32c60Diego Colantoni accountName:accountName
f877f6ca2428244a6d0954a1dbef471577b32c60Diego Colantoni issuer:issuer
f877f6ca2428244a6d0954a1dbef471577b32c60Diego Colantoni image:[[NSURL alloc]initWithString:imageURL]
f877f6ca2428244a6d0954a1dbef471577b32c60Diego Colantoni backgroundColor:bgColor];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott // Check if we already have generated this identity, in which case re-use.
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott BOOL add = true;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott for (FRAIdentity *identity in identities) {
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott if ([newIdentity.issuer isEqualToString:identity.issuer] && [newIdentity.accountName isEqualToString:identity.accountName]) {
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott newIdentity = identity;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott add = false;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott break;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott }
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott }
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott if (add) {
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott [identities addObject:newIdentity];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott }
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott // Formatter for parsing numbers from Strings.
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott numberFormatter.numberStyle = NSNumberFormatterDecimalStyle;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott // Create the Mechanism
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni if ([type isEqualToString:[FRAHotpOathMechanism mechanismType]]) {
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott // Options Map is a String to String mapping stored in JSON.
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott NSDictionary *optionsMap;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott if (![FRASerialization deserializeJSON:optionsJSON intoDictionary:&optionsMap error:error]) {
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott return nil;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott }
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott // Secret Key - Base 64 encoded bytes
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott NSString *secretValue = [optionsMap objectForKey:OATH_MECHANISM_SECRET];
0fc1bec9becddcbec0d26541dd7ef40b43c0a67bKen Stubbings NSData* secret = [FRASerialization deserializeSecret:secretValue];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott // Algorithm - String enumeration
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott NSString *algorithmValue = [optionsMap objectForKey:OATH_MECHANISM_ALGORITHM];
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni CCHmacAlgorithm algorithm = [FRAOathCode fromString:algorithmValue];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni // Code Length - String value of Integer
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni NSString *codeLengthValue = [optionsMap objectForKey:OATH_MECHANISM_DIGITS];
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni int codeLength = [[numberFormatter numberFromString:codeLengthValue] intValue];
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni // Counter - String value of unsigned Long Long
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni NSString *counterValue = [optionsMap objectForKey:OATH_MECHANISM_COUNTER];
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni u_int64_t counter = [[numberFormatter numberFromString:counterValue] unsignedLongLongValue];
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni FRAHotpOathMechanism *newMechanism = [FRAHotpOathMechanism mechanismWithDatabase:identityDatabase
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni identityModel:identityModel
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni secretKey:secret
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni HMACAlgorithm:algorithm
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni codeLength:codeLength
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni counter:counter];
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni // Note: We are not de-duplicating OATH Mechanism because they will not be duplicated in the SQL results.
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni if (![newIdentity addMechanism:newMechanism error:error]) {
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni return nil;
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni }
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni } else if ([type isEqualToString:[FRATotpOathMechanism mechanismType]]) {
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni // Options Map is a String to String mapping stored in JSON.
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni NSDictionary *optionsMap;
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni if (![FRASerialization deserializeJSON:optionsJSON intoDictionary:&optionsMap error:error]) {
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni return nil;
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni }
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni // Secret Key - Base 64 encoded bytes
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni NSString *secretValue = [optionsMap objectForKey:OATH_MECHANISM_SECRET];
6ca6bef8bd63e8c1fd132e38f8e3904b8d2ad172Ken Stubbings NSData* secret = [FRASerialization deserializeSecret:secretValue];
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni // Algorithm - String enumeration
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni NSString *algorithmValue = [optionsMap objectForKey:OATH_MECHANISM_ALGORITHM];
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni CCHmacAlgorithm algorithm = [FRAOathCode fromString:algorithmValue];
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni // Code Length - String value of Integer
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni NSString *codeLengthValue = [optionsMap objectForKey:OATH_MECHANISM_DIGITS];
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni int codeLength = [[numberFormatter numberFromString:codeLengthValue] intValue];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott // Period - String value of unsigned Integer
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott NSString *periodValue = [optionsMap objectForKey:OATH_MECHANISM_PERIOD];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott u_int32_t period = [[numberFormatter numberFromString:periodValue] unsignedIntValue];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni FRATotpOathMechanism *newMechanism = [FRATotpOathMechanism mechanismWithDatabase:identityDatabase
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni identityModel:identityModel
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni secretKey:secret
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni HMACAlgorithm:algorithm
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni codeLength:codeLength
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni period:period];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni // Note: We are not de-duplicating OATH Mechanism because they will not be duplicated in the SQL results.
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott if (![newIdentity addMechanism:newMechanism error:error]) {
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott return nil;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott }
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
caa9e77dc369fea8df9ae2c598d3c83b7214c1cfDiego Colantoni } else if ([type isEqualToString:[FRAPushMechanism mechanismType]]) {
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott // Options Map is a String to String mapping stored in JSON.
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott NSDictionary *optionsMap;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott if (![FRASerialization deserializeJSON:optionsJSON intoDictionary:&optionsMap error:error]) {
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott return nil;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott }
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott // Secret stored as String (Base64?)
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott NSString *secretValue = [optionsMap objectForKey:PUSH_MECHANISM_SECRET];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott // Auth Endpoint as string
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott NSString *authEndpointValue = [optionsMap objectForKey:PUSH_MECHANISM_AUTH_END_POINT];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott // Version as string
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott NSString *versionString = [optionsMap objectForKey:PUSH_MECHANISM_VERSION];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott NSInteger version = [[numberFormatter numberFromString:versionString] integerValue];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
f877f6ca2428244a6d0954a1dbef471577b32c60Diego Colantoni FRAPushMechanism *newMechanism = [FRAPushMechanism pushMechanismWithDatabase:identityDatabase
f877f6ca2428244a6d0954a1dbef471577b32c60Diego Colantoni identityModel:identityModel
f877f6ca2428244a6d0954a1dbef471577b32c60Diego Colantoni authEndpoint:authEndpointValue
f877f6ca2428244a6d0954a1dbef471577b32c60Diego Colantoni secret:secretValue
f877f6ca2428244a6d0954a1dbef471577b32c60Diego Colantoni version:version
f877f6ca2428244a6d0954a1dbef471577b32c60Diego Colantoni mechanismIdentifier:mechanismUID];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott // Check to see if we already have this PushMechanism present, otherwise add it in.
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott BOOL add = true;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott for (FRAMechanism *mechanism in newIdentity.mechanisms) {
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott if ([mechanism isKindOfClass:[FRAPushMechanism class]]) {
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott FRAPushMechanism *pushMechanism = (FRAPushMechanism *)mechanism;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott if ([pushMechanism.mechanismUID isEqualToString:newMechanism.mechanismUID]) {
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott newMechanism = pushMechanism;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott add = false;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott break;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott }
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott }
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott }
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott if (add) {
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott if (![newIdentity addMechanism:newMechanism error:error]) {
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott return nil;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott }
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott }
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott // If we have a notification, parse and create the Notification for the Push Mechanism.
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott // Note: Notifications can only currently exist for PushMechanisms.
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott if (timeReceived != nil && [timeReceived length] > 0) {
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott
5d37db6a3aca50ba14cba8909d3ae44f7d43e407Ken Stubbings // Extract notifcation data from database
5d37db6a3aca50ba14cba8909d3ae44f7d43e407Ken Stubbings NSDate *dateTimeReceived = [NSDate dateWithTimeIntervalSince1970:[timeReceived doubleValue]];
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott NSDictionary *dataMap;
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott if (![FRASerialization deserializeJSON:data intoDictionary:&dataMap error:error]) {
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott return nil;
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott }
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott NSString *messageId = [dataMap valueForKey:NOTIFICATION_MESSAGE_ID];
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott NSString *challenge = [[NSString alloc] initWithData:[FRASerialization deserializeBytes:[dataMap valueForKey:NOTIFICATION_PUSH_CHALLENGE]] encoding:NSUTF8StringEncoding];
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott NSTimeInterval ttl = [[dataMap valueForKey:NOTIFICATION_TIME_TO_LIVE] doubleValue];
5d37db6a3aca50ba14cba8909d3ae44f7d43e407Ken Stubbings NSString *loadBalancerCookieData = [dataMap valueForKey:NOTIFICATION_LOAD_BALANCER_COOKIE];
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott
5d37db6a3aca50ba14cba8909d3ae44f7d43e407Ken Stubbings // recreate notificaiton
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott FRANotification *notification = [FRANotification notificationWithDatabase:identityDatabase
f877f6ca2428244a6d0954a1dbef471577b32c60Diego Colantoni identityModel:identityModel
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott messageId:messageId
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott challenge:challenge
5d37db6a3aca50ba14cba8909d3ae44f7d43e407Ken Stubbings timeReceived:dateTimeReceived
465ea459a87d4605e145d8f45b6a9c104b696e3bCraig McDonnell timeToLive:ttl
5d37db6a3aca50ba14cba8909d3ae44f7d43e407Ken Stubbings loadBalancerCookieData:loadBalancerCookieData
465ea459a87d4605e145d8f45b6a9c104b696e3bCraig McDonnell pending:pending
465ea459a87d4605e145d8f45b6a9c104b696e3bCraig McDonnell approved:approved];
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott if (![newMechanism addNotification:notification error:error]) {
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott return nil;
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott }
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott }
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott } else {
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott @throw [FRAError createIllegalStateException:@"Invalid mechanism"];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott }
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott }
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott // As we have read the objects from the database, marked them as stored.
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott for (FRAIdentity* identity in identities) {
55abfb9b58693eddac5205e74aac84f50c9798d2Robert Wapshott identity.stored = YES;
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott for (FRAMechanism *mechanism in identity.mechanisms) {
55abfb9b58693eddac5205e74aac84f50c9798d2Robert Wapshott mechanism.stored = YES;
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott for (FRANotification *notification in mechanism.notifications) {
55abfb9b58693eddac5205e74aac84f50c9798d2Robert Wapshott notification.stored = YES;
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott }
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott }
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott }
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott
2ff6fc247a59e7bebd6f71595469a511fe7456efRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott return identities;
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott }
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott @finally {
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott [sqlDatabase closeConnectionToDatabase:database];
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott }
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott}
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott
721bb987c406979bcfe705fa1ca8d54497d40fcbRobert Wapshott@end