2
0

Element -> Site

This commit is contained in:
Maarten Billemont 2014-09-21 11:47:53 -04:00
parent b3a0b6a7c0
commit 5b85ba3a4b
25 changed files with 337 additions and 338 deletions

View File

@ -16,8 +16,8 @@
// //
#import "MPKey.h" #import "MPKey.h"
#import "MPSiteStoredEntity.h" #import "MPStoredSiteEntity.h"
#import "MPSiteGeneratedEntity.h" #import "MPGeneratedSiteEntity.h"
#define MPAlgorithmDefaultVersion 1 #define MPAlgorithmDefaultVersion 1
#define MPAlgorithmDefault MPAlgorithmForVersion(MPAlgorithmDefaultVersion) #define MPAlgorithmDefault MPAlgorithmForVersion(MPAlgorithmDefaultVersion)
@ -66,8 +66,8 @@ NSString *NSStringFromTimeToCrack(TimeToCrack timeToCrack);
- (NSString *)generateContentForSiteNamed:(NSString *)name ofType:(MPSiteType)type withCounter:(NSUInteger)counter - (NSString *)generateContentForSiteNamed:(NSString *)name ofType:(MPSiteType)type withCounter:(NSUInteger)counter
variant:(MPSiteVariant)variant usingKey:(MPKey *)key; variant:(MPSiteVariant)variant usingKey:(MPKey *)key;
- (NSString *)storedLoginForSite:(MPSiteStoredEntity *)site usingKey:(MPKey *)key; - (NSString *)storedLoginForSite:(MPStoredSiteEntity *)site usingKey:(MPKey *)key;
- (NSString *)storedPasswordForSite:(MPSiteStoredEntity *)site usingKey:(MPKey *)key; - (NSString *)storedPasswordForSite:(MPStoredSiteEntity *)site usingKey:(MPKey *)key;
- (BOOL)savePassword:(NSString *)clearPassword toSite:(MPSiteEntity *)site usingKey:(MPKey *)siteKey; - (BOOL)savePassword:(NSString *)clearPassword toSite:(MPSiteEntity *)site usingKey:(MPKey *)siteKey;

View File

@ -77,35 +77,35 @@
NSError *error = nil; NSError *error = nil;
NSFetchRequest *migrationRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPSiteEntity class] )]; NSFetchRequest *migrationRequest = [NSFetchRequest fetchRequestWithEntityName:NSStringFromClass( [MPSiteEntity class] )];
migrationRequest.predicate = [NSPredicate predicateWithFormat:@"version_ < %d AND user == %@", self.version, user]; migrationRequest.predicate = [NSPredicate predicateWithFormat:@"version_ < %d AND user == %@", self.version, user];
NSArray *migrationElements = [moc executeFetchRequest:migrationRequest error:&error]; NSArray *migrationSites = [moc executeFetchRequest:migrationRequest error:&error];
if (!migrationElements) { if (!migrationSites) {
err( @"While looking for elements to migrate: %@", error ); err( @"While looking for sites to migrate: %@", error );
return NO; return NO;
} }
BOOL requiresExplicitMigration = NO; BOOL requiresExplicitMigration = NO;
for (MPSiteEntity *migrationElement in migrationElements) for (MPSiteEntity *migrationSite in migrationSites)
if (![migrationElement migrateExplicitly:NO]) if (![migrationSite migrateExplicitly:NO])
requiresExplicitMigration = YES; requiresExplicitMigration = YES;
return requiresExplicitMigration; return requiresExplicitMigration;
} }
- (BOOL)migrateSite:(MPSiteEntity *)element explicit:(BOOL)explicit { - (BOOL)migrateSite:(MPSiteEntity *)site explicit:(BOOL)explicit {
if (element.version != [self version] - 1) if (site.version != [self version] - 1)
// Only migrate from previous version. // Only migrate from previous version.
return NO; return NO;
if (!explicit) { if (!explicit) {
// This migration requires explicit permission. // This migration requires explicit permission.
element.requiresExplicitMigration = YES; site.requiresExplicitMigration = YES;
return NO; return NO;
} }
// Apply migration. // Apply migration.
element.requiresExplicitMigration = NO; site.requiresExplicitMigration = NO;
element.version = [self version]; site.version = [self version];
return YES; return YES;
} }
@ -242,34 +242,34 @@
switch (type) { switch (type) {
case MPSiteTypeGeneratedMaximum: case MPSiteTypeGeneratedMaximum:
return [MPElementGeneratedEntity class]; return [MPGeneratedSiteEntity class];
case MPSiteTypeGeneratedLong: case MPSiteTypeGeneratedLong:
return [MPElementGeneratedEntity class]; return [MPGeneratedSiteEntity class];
case MPSiteTypeGeneratedMedium: case MPSiteTypeGeneratedMedium:
return [MPElementGeneratedEntity class]; return [MPGeneratedSiteEntity class];
case MPSiteTypeGeneratedBasic: case MPSiteTypeGeneratedBasic:
return [MPElementGeneratedEntity class]; return [MPGeneratedSiteEntity class];
case MPSiteTypeGeneratedShort: case MPSiteTypeGeneratedShort:
return [MPElementGeneratedEntity class]; return [MPGeneratedSiteEntity class];
case MPSiteTypeGeneratedPIN: case MPSiteTypeGeneratedPIN:
return [MPElementGeneratedEntity class]; return [MPGeneratedSiteEntity class];
case MPSiteTypeGeneratedName: case MPSiteTypeGeneratedName:
return [MPElementGeneratedEntity class]; return [MPGeneratedSiteEntity class];
case MPSiteTypeGeneratedPhrase: case MPSiteTypeGeneratedPhrase:
return [MPElementGeneratedEntity class]; return [MPGeneratedSiteEntity class];
case MPSiteTypeStoredPersonal: case MPSiteTypeStoredPersonal:
return [MPSiteStoredEntity class]; return [MPStoredSiteEntity class];
case MPSiteTypeStoredDevicePrivate: case MPSiteTypeStoredDevicePrivate:
return [MPSiteStoredEntity class]; return [MPStoredSiteEntity class];
} }
Throw( @"Type not supported: %lu", (long)type ); Throw( @"Type not supported: %lu", (long)type );
@ -413,20 +413,20 @@
return content; return content;
} }
- (NSString *)storedLoginForSite:(MPSiteStoredEntity *)element usingKey:(MPKey *)key { - (NSString *)storedLoginForSite:(MPStoredSiteEntity *)site usingKey:(MPKey *)key {
return nil; return nil;
} }
- (NSString *)storedPasswordForSite:(MPSiteStoredEntity *)element usingKey:(MPKey *)key { - (NSString *)storedPasswordForSite:(MPStoredSiteEntity *)site usingKey:(MPKey *)key {
return [self decryptContent:element.contentObject usingKey:key]; return [self decryptContent:site.contentObject usingKey:key];
} }
- (BOOL)savePassword:(NSString *)clearContent toSite:(MPSiteEntity *)element usingKey:(MPKey *)elementKey { - (BOOL)savePassword:(NSString *)clearContent toSite:(MPSiteEntity *)site usingKey:(MPKey *)siteKey {
NSAssert( [elementKey.keyID isEqualToData:element.user.keyID], @"Element does not belong to current user." ); NSAssert( [siteKey.keyID isEqualToData:site.user.keyID], @"Site does not belong to current user." );
switch (element.type) { switch (site.type) {
case MPSiteTypeGeneratedMaximum: case MPSiteTypeGeneratedMaximum:
case MPSiteTypeGeneratedLong: case MPSiteTypeGeneratedLong:
case MPSiteTypeGeneratedMedium: case MPSiteTypeGeneratedMedium:
@ -435,58 +435,58 @@
case MPSiteTypeGeneratedPIN: case MPSiteTypeGeneratedPIN:
case MPSiteTypeGeneratedName: case MPSiteTypeGeneratedName:
case MPSiteTypeGeneratedPhrase: { case MPSiteTypeGeneratedPhrase: {
wrn( @"Cannot save content to element with generated type %lu.", (long)element.type ); wrn( @"Cannot save content to site with generated type %lu.", (long)site.type );
return NO; return NO;
} }
case MPSiteTypeStoredPersonal: { case MPSiteTypeStoredPersonal: {
if (![element isKindOfClass:[MPSiteStoredEntity class]]) { if (![site isKindOfClass:[MPStoredSiteEntity class]]) {
wrn( @"Element with stored type %lu is not an MPSiteStoredEntity, but a %@.", wrn( @"Site with stored type %lu is not an MPStoredSiteEntity, but a %@.",
(long)element.type, [element class] ); (long)site.type, [site class] );
return NO; return NO;
} }
NSData *encryptedContent = [[clearContent dataUsingEncoding:NSUTF8StringEncoding] NSData *encryptedContent = [[clearContent dataUsingEncoding:NSUTF8StringEncoding]
encryptWithSymmetricKey:[elementKey subKeyOfLength:PearlCryptKeySize].keyData padding:YES]; encryptWithSymmetricKey:[siteKey subKeyOfLength:PearlCryptKeySize].keyData padding:YES];
if ([((MPSiteStoredEntity *)element).contentObject isEqualToData:encryptedContent]) if ([((MPStoredSiteEntity *)site).contentObject isEqualToData:encryptedContent])
return NO; return NO;
((MPSiteStoredEntity *)element).contentObject = encryptedContent; ((MPStoredSiteEntity *)site).contentObject = encryptedContent;
return YES; return YES;
} }
case MPSiteTypeStoredDevicePrivate: { case MPSiteTypeStoredDevicePrivate: {
if (![element isKindOfClass:[MPSiteStoredEntity class]]) { if (![site isKindOfClass:[MPStoredSiteEntity class]]) {
wrn( @"Element with stored type %lu is not an MPSiteStoredEntity, but a %@.", wrn( @"Site with stored type %lu is not an MPStoredSiteEntity, but a %@.",
(long)element.type, [element class] ); (long)site.type, [site class] );
return NO; return NO;
} }
NSData *encryptedContent = [[clearContent dataUsingEncoding:NSUTF8StringEncoding] NSData *encryptedContent = [[clearContent dataUsingEncoding:NSUTF8StringEncoding]
encryptWithSymmetricKey:[elementKey subKeyOfLength:PearlCryptKeySize].keyData padding:YES]; encryptWithSymmetricKey:[siteKey subKeyOfLength:PearlCryptKeySize].keyData padding:YES];
NSDictionary *elementQuery = [self queryForDevicePrivateElementNamed:element.name]; NSDictionary *siteQuery = [self queryForDevicePrivateSiteNamed:site.name];
if (!encryptedContent) if (!encryptedContent)
[PearlKeyChain deleteItemForQuery:elementQuery]; [PearlKeyChain deleteItemForQuery:siteQuery];
else else
[PearlKeyChain addOrUpdateItemForQuery:elementQuery withAttributes:@{ [PearlKeyChain addOrUpdateItemForQuery:siteQuery withAttributes:@{
(__bridge id)kSecValueData : encryptedContent, (__bridge id)kSecValueData : encryptedContent,
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
(__bridge id)kSecAttrAccessible : (__bridge id)kSecAttrAccessibleWhenUnlockedThisDeviceOnly, (__bridge id)kSecAttrAccessible : (__bridge id)kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
#endif #endif
}]; }];
((MPSiteStoredEntity *)element).contentObject = nil; ((MPStoredSiteEntity *)site).contentObject = nil;
return YES; return YES;
} }
} }
Throw( @"Unsupported type: %ld", (long)element.type ); Throw( @"Unsupported type: %ld", (long)site.type );
} }
- (NSString *)resolveLoginForSite:(MPSiteEntity *)element usingKey:(MPKey *)elementKey { - (NSString *)resolveLoginForSite:(MPSiteEntity *)site usingKey:(MPKey *)siteKey {
dispatch_group_t group = dispatch_group_create(); dispatch_group_t group = dispatch_group_create();
dispatch_group_enter( group ); dispatch_group_enter( group );
__block NSString *result = nil; __block NSString *result = nil;
[self resolveLoginForSite:element usingKey:elementKey result:^(NSString *result_) { [self resolveLoginForSite:site usingKey:siteKey result:^(NSString *result_) {
result = result_; result = result_;
dispatch_group_leave( group ); dispatch_group_leave( group );
}]; }];
@ -495,12 +495,12 @@
return result; return result;
} }
- (NSString *)resolvePasswordForSite:(MPSiteEntity *)element usingKey:(MPKey *)elementKey { - (NSString *)resolvePasswordForSite:(MPSiteEntity *)site usingKey:(MPKey *)siteKey {
dispatch_group_t group = dispatch_group_create(); dispatch_group_t group = dispatch_group_create();
dispatch_group_enter( group ); dispatch_group_enter( group );
__block NSString *result = nil; __block NSString *result = nil;
[self resolvePasswordForSite:element usingKey:elementKey result:^(NSString *result_) { [self resolvePasswordForSite:site usingKey:siteKey result:^(NSString *result_) {
result = result_; result = result_;
dispatch_group_leave( group ); dispatch_group_leave( group );
}]; }];
@ -509,32 +509,32 @@
return result; return result;
} }
- (void)resolveLoginForSite:(MPSiteEntity *)element usingKey:(MPKey *)elementKey result:(void ( ^ )(NSString *result))resultBlock { - (void)resolveLoginForSite:(MPSiteEntity *)site usingKey:(MPKey *)siteKey result:(void ( ^ )(NSString *result))resultBlock {
NSAssert( [elementKey.keyID isEqualToData:element.user.keyID], @"Element does not belong to current user." ); NSAssert( [siteKey.keyID isEqualToData:site.user.keyID], @"Site does not belong to current user." );
NSString *name = element.name; NSString *name = site.name;
BOOL loginGenerated = element.loginGenerated && [[MPAppDelegate_Shared get] isPurchased:MPProductGenerateLogins]; BOOL loginGenerated = site.loginGenerated && [[MPAppDelegate_Shared get] isPurchased:MPProductGenerateLogins];
NSString *loginName = loginGenerated? nil: element.loginName; NSString *loginName = loginGenerated? nil: site.loginName;
id<MPAlgorithm> algorithm = nil; id<MPAlgorithm> algorithm = nil;
if (!name.length) if (!name.length)
err( @"Missing name." ); err( @"Missing name." );
else if (!elementKey.keyData.length) else if (!siteKey.keyData.length)
err( @"Missing key." ); err( @"Missing key." );
else else
algorithm = element.algorithm; algorithm = site.algorithm;
dispatch_async( dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{ dispatch_async( dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{
if (loginGenerated) if (loginGenerated)
resultBlock( [algorithm generateLoginForSiteNamed:name usingKey:elementKey] ); resultBlock( [algorithm generateLoginForSiteNamed:name usingKey:siteKey] );
else else
resultBlock( loginName ); resultBlock( loginName );
} ); } );
} }
- (void)resolvePasswordForSite:(MPSiteEntity *)element usingKey:(MPKey *)elementKey result:(void ( ^ )(NSString *result))resultBlock { - (void)resolvePasswordForSite:(MPSiteEntity *)site usingKey:(MPKey *)siteKey result:(void ( ^ )(NSString *result))resultBlock {
NSAssert( [elementKey.keyID isEqualToData:element.user.keyID], @"Element does not belong to current user." ); NSAssert( [siteKey.keyID isEqualToData:site.user.keyID], @"Site does not belong to current user." );
switch (element.type) { switch (site.type) {
case MPSiteTypeGeneratedMaximum: case MPSiteTypeGeneratedMaximum:
case MPSiteTypeGeneratedLong: case MPSiteTypeGeneratedLong:
case MPSiteTypeGeneratedMedium: case MPSiteTypeGeneratedMedium:
@ -543,55 +543,55 @@
case MPSiteTypeGeneratedPIN: case MPSiteTypeGeneratedPIN:
case MPSiteTypeGeneratedName: case MPSiteTypeGeneratedName:
case MPSiteTypeGeneratedPhrase: { case MPSiteTypeGeneratedPhrase: {
if (![element isKindOfClass:[MPElementGeneratedEntity class]]) { if (![site isKindOfClass:[MPGeneratedSiteEntity class]]) {
wrn( @"Element with generated type %lu is not an MPSiteGeneratedEntity, but a %@.", wrn( @"Site with generated type %lu is not an MPGeneratedSiteEntity, but a %@.",
(long)element.type, [element class] ); (long)site.type, [site class] );
break; break;
} }
NSString *name = element.name; NSString *name = site.name;
MPSiteType type = element.type; MPSiteType type = site.type;
NSUInteger counter = ((MPElementGeneratedEntity *)element).counter; NSUInteger counter = ((MPGeneratedSiteEntity *)site).counter;
id<MPAlgorithm> algorithm = nil; id<MPAlgorithm> algorithm = nil;
if (!element.name.length) if (!site.name.length)
err( @"Missing name." ); err( @"Missing name." );
else if (!elementKey.keyData.length) else if (!siteKey.keyData.length)
err( @"Missing key." ); err( @"Missing key." );
else else
algorithm = element.algorithm; algorithm = site.algorithm;
dispatch_async( dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{ dispatch_async( dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{
NSString *result = [algorithm generatePasswordForSiteNamed:name ofType:type withCounter:counter usingKey:elementKey]; NSString *result = [algorithm generatePasswordForSiteNamed:name ofType:type withCounter:counter usingKey:siteKey];
resultBlock( result ); resultBlock( result );
} ); } );
break; break;
} }
case MPSiteTypeStoredPersonal: { case MPSiteTypeStoredPersonal: {
if (![element isKindOfClass:[MPSiteStoredEntity class]]) { if (![site isKindOfClass:[MPStoredSiteEntity class]]) {
wrn( @"Element with stored type %lu is not an MPSiteStoredEntity, but a %@.", wrn( @"Site with stored type %lu is not an MPStoredSiteEntity, but a %@.",
(long)element.type, [element class] ); (long)site.type, [site class] );
break; break;
} }
NSData *encryptedContent = ((MPSiteStoredEntity *)element).contentObject; NSData *encryptedContent = ((MPStoredSiteEntity *)site).contentObject;
dispatch_async( dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{ dispatch_async( dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{
NSString *result = [self decryptContent:encryptedContent usingKey:elementKey]; NSString *result = [self decryptContent:encryptedContent usingKey:siteKey];
resultBlock( result ); resultBlock( result );
} ); } );
break; break;
} }
case MPSiteTypeStoredDevicePrivate: { case MPSiteTypeStoredDevicePrivate: {
NSAssert( [element isKindOfClass:[MPSiteStoredEntity class]], NSAssert( [site isKindOfClass:[MPStoredSiteEntity class]],
@"Element with stored type %lu is not an MPSiteStoredEntity, but a %@.", (long)element.type, @"Site with stored type %lu is not an MPStoredSiteEntity, but a %@.", (long)site.type,
[element class] ); [site class] );
NSDictionary *elementQuery = [self queryForDevicePrivateElementNamed:element.name]; NSDictionary *siteQuery = [self queryForDevicePrivateSiteNamed:site.name];
NSData *encryptedContent = [PearlKeyChain dataOfItemForQuery:elementQuery]; NSData *encryptedContent = [PearlKeyChain dataOfItemForQuery:siteQuery];
dispatch_async( dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{ dispatch_async( dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0 ), ^{
NSString *result = [self decryptContent:encryptedContent usingKey:elementKey]; NSString *result = [self decryptContent:encryptedContent usingKey:siteKey];
resultBlock( result ); resultBlock( result );
} ); } );
break; break;
@ -600,10 +600,10 @@
} }
- (void)importProtectedPassword:(NSString *)protectedContent protectedByKey:(MPKey *)importKey - (void)importProtectedPassword:(NSString *)protectedContent protectedByKey:(MPKey *)importKey
intoSite:(MPSiteEntity *)element usingKey:(MPKey *)elementKey { intoSite:(MPSiteEntity *)site usingKey:(MPKey *)siteKey {
NSAssert( [elementKey.keyID isEqualToData:element.user.keyID], @"Element does not belong to current user." ); NSAssert( [siteKey.keyID isEqualToData:site.user.keyID], @"Site does not belong to current user." );
switch (element.type) { switch (site.type) {
case MPSiteTypeGeneratedMaximum: case MPSiteTypeGeneratedMaximum:
case MPSiteTypeGeneratedLong: case MPSiteTypeGeneratedLong:
case MPSiteTypeGeneratedMedium: case MPSiteTypeGeneratedMedium:
@ -615,17 +615,17 @@
break; break;
case MPSiteTypeStoredPersonal: { case MPSiteTypeStoredPersonal: {
if (![element isKindOfClass:[MPSiteStoredEntity class]]) { if (![site isKindOfClass:[MPStoredSiteEntity class]]) {
wrn( @"Element with stored type %lu is not an MPSiteStoredEntity, but a %@.", wrn( @"Site with stored type %lu is not an MPStoredSiteEntity, but a %@.",
(long)element.type, [element class] ); (long)site.type, [site class] );
break; break;
} }
if ([importKey.keyID isEqualToData:elementKey.keyID]) if ([importKey.keyID isEqualToData:siteKey.keyID])
((MPSiteStoredEntity *)element).contentObject = [protectedContent decodeBase64]; ((MPStoredSiteEntity *)site).contentObject = [protectedContent decodeBase64];
else { else {
NSString *clearContent = [self decryptContent:[protectedContent decodeBase64] usingKey:importKey]; NSString *clearContent = [self decryptContent:[protectedContent decodeBase64] usingKey:importKey];
[self importClearTextPassword:clearContent intoSite:element usingKey:elementKey]; [self importClearTextPassword:clearContent intoSite:site usingKey:siteKey];
} }
break; break;
} }
@ -635,10 +635,10 @@
} }
} }
- (void)importClearTextPassword:(NSString *)clearContent intoSite:(MPSiteEntity *)element usingKey:(MPKey *)elementKey { - (void)importClearTextPassword:(NSString *)clearContent intoSite:(MPSiteEntity *)site usingKey:(MPKey *)siteKey {
NSAssert( [elementKey.keyID isEqualToData:element.user.keyID], @"Element does not belong to current user." ); NSAssert( [siteKey.keyID isEqualToData:site.user.keyID], @"Site does not belong to current user." );
switch (element.type) { switch (site.type) {
case MPSiteTypeGeneratedMaximum: case MPSiteTypeGeneratedMaximum:
case MPSiteTypeGeneratedLong: case MPSiteTypeGeneratedLong:
case MPSiteTypeGeneratedMedium: case MPSiteTypeGeneratedMedium:
@ -650,7 +650,7 @@
break; break;
case MPSiteTypeStoredPersonal: { case MPSiteTypeStoredPersonal: {
[self savePassword:clearContent toSite:element usingKey:elementKey]; [self savePassword:clearContent toSite:site usingKey:siteKey];
break; break;
} }
@ -659,14 +659,14 @@
} }
} }
- (NSString *)exportPasswordForSite:(MPSiteEntity *)element usingKey:(MPKey *)elementKey { - (NSString *)exportPasswordForSite:(MPSiteEntity *)site usingKey:(MPKey *)siteKey {
NSAssert( [elementKey.keyID isEqualToData:element.user.keyID], @"Element does not belong to current user." ); NSAssert( [siteKey.keyID isEqualToData:site.user.keyID], @"Site does not belong to current user." );
if (!(element.type & MPSiteFeatureExportContent)) if (!(site.type & MPSiteFeatureExportContent))
return nil; return nil;
NSString *result = nil; NSString *result = nil;
switch (element.type) { switch (site.type) {
case MPSiteTypeGeneratedMaximum: case MPSiteTypeGeneratedMaximum:
case MPSiteTypeGeneratedLong: case MPSiteTypeGeneratedLong:
case MPSiteTypeGeneratedMedium: case MPSiteTypeGeneratedMedium:
@ -680,12 +680,12 @@
} }
case MPSiteTypeStoredPersonal: { case MPSiteTypeStoredPersonal: {
if (![element isKindOfClass:[MPSiteStoredEntity class]]) { if (![site isKindOfClass:[MPStoredSiteEntity class]]) {
wrn( @"Element with stored type %lu is not an MPSiteStoredEntity, but a %@.", wrn( @"Site with stored type %lu is not an MPStoredSiteEntity, but a %@.",
(long)element.type, [element class] ); (long)site.type, [site class] );
break; break;
} }
result = [((MPSiteStoredEntity *)element).contentObject encodeBase64]; result = [((MPStoredSiteEntity *)site).contentObject encodeBase64];
break; break;
} }
@ -703,7 +703,7 @@
return NO; return NO;
} }
- (NSDictionary *)queryForDevicePrivateElementNamed:(NSString *)name { - (NSDictionary *)queryForDevicePrivateSiteNamed:(NSString *)name {
return [PearlKeyChain createQueryForClass:kSecClassGenericPassword return [PearlKeyChain createQueryForClass:kSecClassGenericPassword
attributes:@{ attributes:@{

View File

@ -25,23 +25,23 @@
return 1; return 1;
} }
- (BOOL)migrateSite:(MPSiteEntity *)element explicit:(BOOL)explicit { - (BOOL)migrateSite:(MPSiteEntity *)site explicit:(BOOL)explicit {
if (element.version != [self version] - 1) if (site.version != [self version] - 1)
// Only migrate from previous version. // Only migrate from previous version.
return NO; return NO;
if (!explicit) { if (!explicit) {
if (element.type & MPSiteTypeClassGenerated) { if (site.type & MPSiteTypeClassGenerated) {
// This migration requires explicit permission for types of the generated class. // This migration requires explicit permission for types of the generated class.
element.requiresExplicitMigration = YES; site.requiresExplicitMigration = YES;
return NO; return NO;
} }
} }
// Apply migration. // Apply migration.
element.requiresExplicitMigration = NO; site.requiresExplicitMigration = NO;
element.version = [self version]; site.version = [self version];
return YES; return YES;
} }

View File

@ -91,8 +91,8 @@ static NSDictionary *keyQuery(MPUserEntity *user) {
if ([password length] && (tryKey = [MPAlgorithmDefault keyForPassword:password ofUserNamed:user.name])) { if ([password length] && (tryKey = [MPAlgorithmDefault keyForPassword:password ofUserNamed:user.name])) {
user.keyID = tryKey.keyID; user.keyID = tryKey.keyID;
// Migrate existing elements. // Migrate existing sites.
[self migrateElementsForUser:user saveInContext:moc toKey:tryKey]; [self migrateSitesForUser:user saveInContext:moc toKey:tryKey];
} }
} }
@ -164,23 +164,23 @@ static NSDictionary *keyQuery(MPUserEntity *user) {
return YES; return YES;
} }
- (void)migrateElementsForUser:(MPUserEntity *)user saveInContext:(NSManagedObjectContext *)moc toKey:(MPKey *)newKey { - (void)migrateSitesForUser:(MPUserEntity *)user saveInContext:(NSManagedObjectContext *)moc toKey:(MPKey *)newKey {
if (![user.elements count]) if (![user.sites count])
// Nothing to migrate. // Nothing to migrate.
return; return;
MPKey *recoverKey = newKey; MPKey *recoverKey = newKey;
#ifdef PEARL_UIKIT #ifdef PEARL_UIKIT
PearlOverlay *activityOverlay = [PearlOverlay showProgressOverlayWithTitle:PearlString( @"Migrating %ld sites...", PearlOverlay *activityOverlay = [PearlOverlay showProgressOverlayWithTitle:PearlString( @"Migrating %ld sites...",
(long)[user.elements count] )]; (long)[user.sites count] )];
#endif #endif
for (MPSiteEntity *element in user.elements) { for (MPSiteEntity *site in user.sites) {
if (element.type & MPSiteTypeClassStored) { if (site.type & MPSiteTypeClassStored) {
NSString *content; NSString *content;
while (!(content = [element.algorithm storedPasswordForSite:(MPElementStoredEntity *)element usingKey:recoverKey])) { while (!(content = [site.algorithm storedPasswordForSite:(MPStoredSiteEntity *)site usingKey:recoverKey])) {
// Failed to decrypt element with the current recoveryKey. Ask user for a new one to use. // Failed to decrypt site with the current recoveryKey. Ask user for a new one to use.
__block NSString *masterPassword = nil; __block NSString *masterPassword = nil;
#ifdef PEARL_UIKIT #ifdef PEARL_UIKIT
@ -188,7 +188,7 @@ static NSDictionary *keyQuery(MPUserEntity *user) {
dispatch_group_enter( recoverPasswordGroup ); dispatch_group_enter( recoverPasswordGroup );
[PearlAlert showAlertWithTitle:@"Enter Old Master Password" [PearlAlert showAlertWithTitle:@"Enter Old Master Password"
message:PearlString( @"Your old master password is required to migrate the stored password for %@", message:PearlString( @"Your old master password is required to migrate the stored password for %@",
element.name ) site.name )
viewStyle:UIAlertViewStyleSecureTextInput viewStyle:UIAlertViewStyleSecureTextInput
initAlert:nil tappedButtonBlock:^(UIAlertView *alert_, NSInteger buttonIndex_) { initAlert:nil tappedButtonBlock:^(UIAlertView *alert_, NSInteger buttonIndex_) {
@try { @try {
@ -208,7 +208,7 @@ static NSDictionary *keyQuery(MPUserEntity *user) {
// Don't Migrate // Don't Migrate
break; break;
recoverKey = [element.algorithm keyForPassword:masterPassword ofUserNamed:user.name]; recoverKey = [site.algorithm keyForPassword:masterPassword ofUserNamed:user.name];
} }
if (!content) if (!content)
@ -216,7 +216,7 @@ static NSDictionary *keyQuery(MPUserEntity *user) {
break; break;
if (![recoverKey isEqualToKey:newKey]) if (![recoverKey isEqualToKey:newKey])
[element.algorithm savePassword:content toSite:element usingKey:newKey]; [site.algorithm savePassword:content toSite:site usingKey:newKey];
} }
} }

View File

@ -28,8 +28,8 @@ typedef NS_ENUM( NSUInteger, MPImportResult ) {
- (MPFixableResult)findAndFixInconsistenciesSaveInContext:(NSManagedObjectContext *)context; - (MPFixableResult)findAndFixInconsistenciesSaveInContext:(NSManagedObjectContext *)context;
/** @param completion The block to execute after adding the element, executed from the main thread with the new element in the main MOC. */ /** @param completion The block to execute after adding the site, executed from the main thread with the new site in the main MOC. */
- (void)addSiteNamed:(NSString *)siteName completion:(void ( ^ )(MPSiteEntity *element, NSManagedObjectContext *context))completion; - (void)addSiteNamed:(NSString *)siteName completion:(void ( ^ )(MPSiteEntity *site, NSManagedObjectContext *context))completion;
- (MPSiteEntity *)changeSite:(MPSiteEntity *)site saveInContext:(NSManagedObjectContext *)context toType:(MPSiteType)type; - (MPSiteEntity *)changeSite:(MPSiteEntity *)site saveInContext:(NSManagedObjectContext *)context toType:(MPSiteType)type;
- (MPImportResult)importSites:(NSString *)importedSitesString - (MPImportResult)importSites:(NSString *)importedSitesString
askImportPassword:(NSString *(^)(NSString *userName))importPassword askImportPassword:(NSString *(^)(NSString *userName))importPassword

View File

@ -7,6 +7,7 @@
// //
#import "MPAppDelegate_Store.h" #import "MPAppDelegate_Store.h"
#import "MPGeneratedSiteEntity.h"
#if TARGET_OS_IPHONE #if TARGET_OS_IPHONE
#define STORE_OPTIONS NSPersistentStoreFileProtectionKey : NSFileProtectionComplete, #define STORE_OPTIONS NSPersistentStoreFileProtectionKey : NSFileProtectionComplete,
@ -656,24 +657,24 @@ PearlAssociatedObjectProperty( NSManagedObjectContext*, MainManagedObjectContext
// Create new site. // Create new site.
NSString *typeEntityName = [MPAlgorithmForVersion( version ) classNameOfType:type]; NSString *typeEntityName = [MPAlgorithmForVersion( version ) classNameOfType:type];
MPSiteEntity *element = [NSEntityDescription insertNewObjectForEntityForName:typeEntityName inManagedObjectContext:context]; MPSiteEntity *site = [NSEntityDescription insertNewObjectForEntityForName:typeEntityName inManagedObjectContext:context];
element.name = siteName; site.name = siteName;
element.loginName = loginName; site.loginName = loginName;
element.user = user; site.user = user;
element.type = type; site.type = type;
element.uses = uses; site.uses = uses;
element.lastUsed = lastUsed; site.lastUsed = lastUsed;
element.version = version; site.version = version;
if ([exportContent length]) { if ([exportContent length]) {
if (clearText) if (clearText)
[element.algorithm importClearTextPassword:exportContent intoSite:element usingKey:userKey]; [site.algorithm importClearTextPassword:exportContent intoSite:site usingKey:userKey];
else else
[element.algorithm importProtectedPassword:exportContent protectedByKey:importKey intoSite:element usingKey:userKey]; [site.algorithm importProtectedPassword:exportContent protectedByKey:importKey intoSite:site usingKey:userKey];
} }
if ([element isKindOfClass:[MPElementGeneratedEntity class]] && counter != NSNotFound) if ([site isKindOfClass:[MPGeneratedSiteEntity class]] && counter != NSNotFound)
((MPElementGeneratedEntity *)element).counter = counter; ((MPGeneratedSiteEntity *)site).counter = counter;
dbg( @"Created Element: %@", [element debugDescription] ); dbg( @"Created Site: %@", [site debugDescription] );
} }
if (![context saveToStore]) if (![context saveToStore])
@ -719,27 +720,27 @@ PearlAssociatedObjectProperty( NSManagedObjectContext*, MainManagedObjectContext
[export appendFormat:@"# used used type name\t name\tpassword\n"]; [export appendFormat:@"# used used type name\t name\tpassword\n"];
// Sites. // Sites.
for (MPSiteEntity *element in activeUser.elements) { for (MPSiteEntity *site in activeUser.sites) {
NSDate *lastUsed = element.lastUsed; NSDate *lastUsed = site.lastUsed;
NSUInteger uses = element.uses; NSUInteger uses = site.uses;
MPSiteType type = element.type; MPSiteType type = site.type;
NSUInteger version = element.version; NSUInteger version = site.version;
NSUInteger counter = 0; NSUInteger counter = 0;
NSString *loginName = element.loginName; NSString *loginName = site.loginName;
NSString *siteName = element.name; NSString *siteName = site.name;
NSString *content = nil; NSString *content = nil;
// Generated-specific // Generated-specific
if ([element isKindOfClass:[MPElementGeneratedEntity class]]) if ([site isKindOfClass:[MPGeneratedSiteEntity class]])
counter = ((MPElementGeneratedEntity *)element).counter; counter = ((MPGeneratedSiteEntity *)site).counter;
// Determine the content to export. // Determine the content to export.
if (!(type & MPSiteFeatureDevicePrivate)) { if (!(type & MPSiteFeatureDevicePrivate)) {
if (revealPasswords) if (revealPasswords)
content = [element.algorithm resolvePasswordForSite:element usingKey:self.key]; content = [site.algorithm resolvePasswordForSite:site usingKey:self.key];
else if (type & MPSiteFeatureExportContent) else if (type & MPSiteFeatureExportContent)
content = [element.algorithm exportPasswordForSite:element usingKey:self.key]; content = [site.algorithm exportPasswordForSite:site usingKey:self.key];
} }
[export appendFormat:@"%@ %8ld %8s %25s\t%25s\t%@\n", [export appendFormat:@"%@ %8ld %8s %25s\t%25s\t%@\n",

View File

@ -8,8 +8,8 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "MPSiteEntity.h" #import "MPSiteEntity.h"
#import "MPSiteStoredEntity.h" #import "MPStoredSiteEntity.h"
#import "MPSiteGeneratedEntity.h" #import "MPGeneratedSiteEntity.h"
#import "MPUserEntity.h" #import "MPUserEntity.h"
#import "MPAlgorithm.h" #import "MPAlgorithm.h"
#import "MPFixable.h" #import "MPFixable.h"
@ -44,7 +44,7 @@
@end @end
@interface MPSiteGeneratedEntity(MP) @interface MPGeneratedSiteEntity(MP)
@property(assign) NSUInteger counter; @property(assign) NSUInteger counter;

View File

@ -8,7 +8,6 @@
#import "MPEntities.h" #import "MPEntities.h"
#import "MPAppDelegate_Shared.h" #import "MPAppDelegate_Shared.h"
#import "MPAppDelegate_Store.h"
@implementation NSManagedObjectContext(MP) @implementation NSManagedObjectContext(MP)
@ -172,7 +171,7 @@
@end @end
@implementation MPSiteGeneratedEntity(MP) @implementation MPGeneratedSiteEntity(MP)
- (MPFixableResult)findAndFixInconsistenciesInContext:(NSManagedObjectContext *)context { - (MPFixableResult)findAndFixInconsistenciesInContext:(NSManagedObjectContext *)context {
@ -225,7 +224,7 @@
@end @end
@implementation MPSiteStoredEntity(MP) @implementation MPStoredSiteEntity(MP)
- (MPFixableResult)findAndFixInconsistenciesInContext:(NSManagedObjectContext *)context { - (MPFixableResult)findAndFixInconsistenciesInContext:(NSManagedObjectContext *)context {

View File

@ -17,26 +17,26 @@
// //
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#import "MPElementModel.h" #import "MPSiteModel.h"
#import "MPElementsTableView.h" #import "MPSitesTableView.h"
@class MPMacAppDelegate; @class MPMacAppDelegate;
@interface MPPasswordWindowController : NSWindowController<NSTextViewDelegate, NSTextFieldDelegate, NSTableViewDataSource, NSTableViewDelegate> @interface MPPasswordWindowController : NSWindowController<NSTextViewDelegate, NSTextFieldDelegate, NSTableViewDataSource, NSTableViewDelegate>
@property(nonatomic) NSMutableArray *elements; @property(nonatomic) NSMutableArray *sites;
@property(nonatomic) NSString *masterPassword; @property(nonatomic) NSString *masterPassword;
@property(nonatomic) BOOL alternatePressed; @property(nonatomic) BOOL alternatePressed;
@property(nonatomic) BOOL locked; @property(nonatomic) BOOL locked;
@property(nonatomic) BOOL newUser; @property(nonatomic) BOOL newUser;
@property(nonatomic, weak) IBOutlet NSArrayController *elementsController; @property(nonatomic, weak) IBOutlet NSArrayController *sitesController;
@property(nonatomic, weak) IBOutlet NSImageView *blurView; @property(nonatomic, weak) IBOutlet NSImageView *blurView;
@property(nonatomic, weak) IBOutlet NSTextField *inputLabel; @property(nonatomic, weak) IBOutlet NSTextField *inputLabel;
@property(nonatomic, weak) IBOutlet NSTextField *securePasswordField; @property(nonatomic, weak) IBOutlet NSTextField *securePasswordField;
@property(nonatomic, weak) IBOutlet NSTextField *revealPasswordField; @property(nonatomic, weak) IBOutlet NSTextField *revealPasswordField;
@property(nonatomic, weak) IBOutlet NSSearchField *siteField; @property(nonatomic, weak) IBOutlet NSSearchField *siteField;
@property(nonatomic, weak) IBOutlet MPElementsTableView *siteTable; @property(nonatomic, weak) IBOutlet MPSitesTableView *siteTable;
@property(nonatomic, weak) IBOutlet NSProgressIndicator *progressView; @property(nonatomic, weak) IBOutlet NSProgressIndicator *progressView;
@property(nonatomic, strong) IBOutlet NSBox *passwordTypesBox; @property(nonatomic, strong) IBOutlet NSBox *passwordTypesBox;

View File

@ -20,7 +20,7 @@
#import "MPPasswordWindowController.h" #import "MPPasswordWindowController.h"
#import "MPMacAppDelegate.h" #import "MPMacAppDelegate.h"
#import "MPAppDelegate_Store.h" #import "MPAppDelegate_Store.h"
#import "MPElementModel.h" #import "MPSiteModel.h"
#import "MPAppDelegate_Key.h" #import "MPAppDelegate_Key.h"
#import "PearlProfiler.h" #import "PearlProfiler.h"
@ -77,7 +77,7 @@
queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
[self updateUser]; [self updateUser];
}]; }];
[self observeKeyPath:@"elementsController.selection" [self observeKeyPath:@"sitesController.selection"
withBlock:^(id from, id to, NSKeyValueChange cause, id _self) { withBlock:^(id from, id to, NSKeyValueChange cause, id _self) {
[_self updateSelection]; [_self updateSelection];
}]; }];
@ -100,7 +100,7 @@
BOOL alternatePressed = (theEvent.modifierFlags & NSAlternateKeyMask) != 0; BOOL alternatePressed = (theEvent.modifierFlags & NSAlternateKeyMask) != 0;
if (alternatePressed != self.alternatePressed) { if (alternatePressed != self.alternatePressed) {
self.alternatePressed = alternatePressed; self.alternatePressed = alternatePressed;
[self.selectedElement updateContent]; [self.selectedSite updateContent];
if (self.locked) { if (self.locked) {
NSTextField *passwordField = self.securePasswordField; NSTextField *passwordField = self.securePasswordField;
@ -169,9 +169,9 @@
}]; }];
} }
- (IBAction)doSearchElements:(id)sender { - (IBAction)doSearchSites:(id)sender {
[self updateElements]; [self updateSites];
} }
#pragma mark - NSTextViewDelegate #pragma mark - NSTextViewDelegate
@ -186,7 +186,7 @@
- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView { - (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
return (NSInteger)[self.elements count]; return (NSInteger)[self.sites count];
} }
#pragma mark - NSTableViewDelegate #pragma mark - NSTableViewDelegate
@ -229,10 +229,10 @@
switch (returnCode) { switch (returnCode) {
case NSAlertFirstButtonReturn: { case NSAlertFirstButtonReturn: {
// "Create" button. // "Create" button.
[[MPMacAppDelegate get] [[MPMacAppDelegate get] addSiteNamed:[self.siteField stringValue] completion:
addSiteNamed:[self.siteField stringValue] completion:^(MPSiteEntity *element, NSManagedObjectContext *context) { ^(MPSiteEntity *site, NSManagedObjectContext *context) {
if (element) if (site)
PearlMainQueue( ^{ [self updateElements]; } ); PearlMainQueue( ^{ [self updateSites]; } );
}]; }];
break; break;
} }
@ -246,9 +246,9 @@
// "Save" button. // "Save" button.
MPSiteType type = (MPSiteType)[self.passwordTypesMatrix.selectedCell tag]; MPSiteType type = (MPSiteType)[self.passwordTypesMatrix.selectedCell tag];
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPSiteEntity *entity = [[MPMacAppDelegate get] changeSite:[self.selectedElement entityInContext:context] MPSiteEntity *entity = [[MPMacAppDelegate get] changeSite:[self.selectedSite entityInContext:context]
saveInContext:context toType:type]; saveInContext:context toType:type];
if ([entity isKindOfClass:[MPElementStoredEntity class]] && ![(MPElementStoredEntity *)entity contentObject].length) if ([entity isKindOfClass:[MPStoredSiteEntity class]] && ![(MPStoredSiteEntity *)entity contentObject].length)
PearlMainQueue( ^{ PearlMainQueue( ^{
[self changePassword:nil]; [self changePassword:nil];
} ); } );
@ -265,7 +265,7 @@
// "Save" button. // "Save" button.
NSString *loginName = [(NSSecureTextField *)alert.accessoryView stringValue]; NSString *loginName = [(NSSecureTextField *)alert.accessoryView stringValue];
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPSiteEntity *entity = [self.selectedElement entityInContext:context]; MPSiteEntity *entity = [self.selectedSite entityInContext:context];
entity.loginName = loginName; entity.loginName = loginName;
[context saveToStore]; [context saveToStore];
}]; }];
@ -281,7 +281,7 @@
// "Save" button. // "Save" button.
NSString *password = [(NSSecureTextField *)alert.accessoryView stringValue]; NSString *password = [(NSSecureTextField *)alert.accessoryView stringValue];
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPSiteEntity *entity = [self.selectedElement entityInContext:context]; MPSiteEntity *entity = [self.selectedSite entityInContext:context];
[entity.algorithm savePassword:password toSite:entity usingKey:[MPMacAppDelegate get].key]; [entity.algorithm savePassword:password toSite:entity usingKey:[MPMacAppDelegate get].key];
[context saveToStore]; [context saveToStore];
}]; }];
@ -296,7 +296,7 @@
case NSAlertFirstButtonReturn: { case NSAlertFirstButtonReturn: {
// "Delete" button. // "Delete" button.
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
[context deleteObject:[self.selectedElement entityInContext:context]]; [context deleteObject:[self.selectedSite entityInContext:context]];
[context saveToStore]; [context saveToStore];
}]; }];
break; break;
@ -314,19 +314,19 @@
return [self.siteField.stringValue stringByReplacingCharactersInRange:self.siteField.currentEditor.selectedRange withString:@""]?: @""; return [self.siteField.stringValue stringByReplacingCharactersInRange:self.siteField.currentEditor.selectedRange withString:@""]?: @"";
} }
- (void)insertObject:(MPElementModel *)model inElementsAtIndex:(NSUInteger)index { - (void)insertObject:(MPSiteModel *)model inSitesAtIndex:(NSUInteger)index {
[self.elements insertObject:model atIndex:index]; [self.sites insertObject:model atIndex:index];
} }
- (void)removeObjectFromElementsAtIndex:(NSUInteger)index { - (void)removeObjectFromSitesAtIndex:(NSUInteger)index {
[self.elements removeObjectAtIndex:index]; [self.sites removeObjectAtIndex:index];
} }
- (MPElementModel *)selectedElement { - (MPSiteModel *)selectedSite {
return [self.elementsController.selectedObjects firstObject]; return [self.sitesController.selectedObjects firstObject];
} }
#pragma mark - Actions #pragma mark - Actions
@ -337,13 +337,13 @@
[[MPMacAppDelegate get] showPopup:sender]; [[MPMacAppDelegate get] showPopup:sender];
} }
- (IBAction)deleteElement:(id)sender { - (IBAction)deleteSite:(id)sender {
NSAlert *alert = [NSAlert new]; NSAlert *alert = [NSAlert new];
[alert addButtonWithTitle:@"Delete"]; [alert addButtonWithTitle:@"Delete"];
[alert addButtonWithTitle:@"Cancel"]; [alert addButtonWithTitle:@"Cancel"];
[alert setMessageText:@"Delete Site?"]; [alert setMessageText:@"Delete Site?"];
[alert setInformativeText:strf( @"Do you want to delete the site named:\n\n%@", self.selectedElement.siteName )]; [alert setInformativeText:strf( @"Do you want to delete the site named:\n\n%@", self.selectedSite.siteName )];
[alert beginSheetModalForWindow:self.window modalDelegate:self [alert beginSheetModalForWindow:self.window modalDelegate:self
didEndSelector:@selector( alertDidEnd:returnCode:contextInfo: ) contextInfo:MPAlertDeleteSite]; didEndSelector:@selector( alertDidEnd:returnCode:contextInfo: ) contextInfo:MPAlertDeleteSite];
} }
@ -354,9 +354,9 @@
[alert addButtonWithTitle:@"Save"]; [alert addButtonWithTitle:@"Save"];
[alert addButtonWithTitle:@"Cancel"]; [alert addButtonWithTitle:@"Cancel"];
[alert setMessageText:@"Change Login Name"]; [alert setMessageText:@"Change Login Name"];
[alert setInformativeText:strf( @"Enter the login name for: %@", self.selectedElement.siteName )]; [alert setInformativeText:strf( @"Enter the login name for: %@", self.selectedSite.siteName )];
NSTextField *loginField = [[NSTextField alloc] initWithFrame:NSMakeRect( 0, 0, 200, 22 )]; NSTextField *loginField = [[NSTextField alloc] initWithFrame:NSMakeRect( 0, 0, 200, 22 )];
loginField.stringValue = self.selectedElement.loginName?: @""; loginField.stringValue = self.selectedSite.loginName?: @"";
[loginField selectText:self]; [loginField selectText:self];
[alert setAccessoryView:loginField]; [alert setAccessoryView:loginField];
[alert layout]; [alert layout];
@ -381,14 +381,14 @@
- (IBAction)changePassword:(id)sender { - (IBAction)changePassword:(id)sender {
if (!self.selectedElement.stored) if (!self.selectedSite.stored)
return; return;
NSAlert *alert = [NSAlert new]; NSAlert *alert = [NSAlert new];
[alert addButtonWithTitle:@"Save"]; [alert addButtonWithTitle:@"Save"];
[alert addButtonWithTitle:@"Cancel"]; [alert addButtonWithTitle:@"Cancel"];
[alert setMessageText:@"Change Password"]; [alert setMessageText:@"Change Password"];
[alert setInformativeText:strf( @"Enter the new password for: %@", self.selectedElement.siteName )]; [alert setInformativeText:strf( @"Enter the new password for: %@", self.selectedSite.siteName )];
[alert setAccessoryView:[[NSSecureTextField alloc] initWithFrame:NSMakeRect( 0, 0, 200, 22 )]]; [alert setAccessoryView:[[NSSecureTextField alloc] initWithFrame:NSMakeRect( 0, 0, 200, 22 )]];
[alert layout]; [alert layout];
[alert beginSheetModalForWindow:self.window modalDelegate:self [alert beginSheetModalForWindow:self.window modalDelegate:self
@ -397,19 +397,19 @@
- (IBAction)changeType:(id)sender { - (IBAction)changeType:(id)sender {
MPElementModel *element = self.selectedElement; MPSiteModel *site = self.selectedSite;
NSArray *types = [element.algorithm allTypesStartingWith:MPSiteTypeGeneratedPIN]; NSArray *types = [site.algorithm allTypesStartingWith:MPSiteTypeGeneratedPIN];
[self.passwordTypesMatrix renewRows:(NSInteger)[types count] columns:1]; [self.passwordTypesMatrix renewRows:(NSInteger)[types count] columns:1];
for (NSUInteger t = 0; t < [types count]; ++t) { for (NSUInteger t = 0; t < [types count]; ++t) {
MPSiteType type = [types[t] unsignedIntegerValue]; MPSiteType type = [types[t] unsignedIntegerValue];
NSString *title = [element.algorithm nameOfType:type]; NSString *title = [site.algorithm nameOfType:type];
if (type & MPSiteTypeClassGenerated) if (type & MPSiteTypeClassGenerated)
title = [element.algorithm generatePasswordForSiteNamed:element.siteName ofType:type title = [site.algorithm generatePasswordForSiteNamed:site.siteName ofType:type
withCounter:element.counter usingKey:[MPMacAppDelegate get].key]; withCounter:site.counter usingKey:[MPMacAppDelegate get].key];
NSButtonCell *cell = [self.passwordTypesMatrix cellAtRow:(NSInteger)t column:0]; NSButtonCell *cell = [self.passwordTypesMatrix cellAtRow:(NSInteger)t column:0];
cell.tag = type; cell.tag = type;
cell.state = type == element.type? NSOnState: NSOffState; cell.state = type == site.type? NSOnState: NSOffState;
cell.title = title; cell.title = title;
} }
@ -417,7 +417,7 @@
[alert addButtonWithTitle:@"Save"]; [alert addButtonWithTitle:@"Save"];
[alert addButtonWithTitle:@"Cancel"]; [alert addButtonWithTitle:@"Cancel"];
[alert setMessageText:@"Change Password Type"]; [alert setMessageText:@"Change Password Type"];
[alert setInformativeText:strf( @"Choose a new password type for: %@", element.siteName )]; [alert setInformativeText:strf( @"Choose a new password type for: %@", site.siteName )];
[alert setAccessoryView:self.passwordTypesBox]; [alert setAccessoryView:self.passwordTypesBox];
[alert layout]; [alert layout];
[alert beginSheetModalForWindow:self.window modalDelegate:self [alert beginSheetModalForWindow:self.window modalDelegate:self
@ -429,11 +429,11 @@
- (BOOL)handleCommand:(SEL)commandSelector { - (BOOL)handleCommand:(SEL)commandSelector {
if (commandSelector == @selector( moveUp: )) { if (commandSelector == @selector( moveUp: )) {
[self.elementsController selectPrevious:self]; [self.sitesController selectPrevious:self];
return YES; return YES;
} }
if (commandSelector == @selector( moveDown: )) { if (commandSelector == @selector( moveDown: )) {
[self.elementsController selectNext:self]; [self.sitesController selectNext:self];
return YES; return YES;
} }
if (commandSelector == @selector( insertNewline: )) { if (commandSelector == @selector( insertNewline: )) {
@ -450,19 +450,19 @@
- (void)useSite { - (void)useSite {
MPElementModel *selectedElement = [self selectedElement]; MPSiteModel *selectedSite = [self selectedSite];
if (selectedElement) { if (selectedSite) {
// Performing action while content is available. Copy it. // Performing action while content is available. Copy it.
[self copyContent:selectedElement.content]; [self copyContent:selectedSite.content];
[self fadeOut]; [self fadeOut];
NSUserNotification *notification = [NSUserNotification new]; NSUserNotification *notification = [NSUserNotification new];
notification.title = @"Password Copied"; notification.title = @"Password Copied";
if (selectedElement.loginName.length) if (selectedSite.loginName.length)
notification.subtitle = strf( @"%@ at %@", selectedElement.loginName, selectedElement.siteName ); notification.subtitle = strf( @"%@ at %@", selectedSite.loginName, selectedSite.siteName );
else else
notification.subtitle = selectedElement.siteName; notification.subtitle = selectedSite.siteName;
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification]; [[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
} }
else { else {
@ -500,18 +500,18 @@
} }
} }
[self updateElements]; [self updateSites];
}]; }];
} }
- (void)updateElements { - (void)updateSites {
if (![MPMacAppDelegate get].key) { if (![MPMacAppDelegate get].key) {
self.elements = nil; self.sites = nil;
return; return;
} }
PearlProfiler *profiler = [PearlProfiler profilerForTask:@"updateElements"]; PearlProfiler *profiler = [PearlProfiler profilerForTask:@"updateSites"];
NSString *query = [self query]; NSString *query = [self query];
[profiler finishJob:@"query"]; [profiler finishJob:@"query"];
[MPMacAppDelegate managedObjectContextPerformBlockAndWait:^(NSManagedObjectContext *context) { [MPMacAppDelegate managedObjectContextPerformBlockAndWait:^(NSManagedObjectContext *context) {
@ -524,17 +524,17 @@
NSError *error = nil; NSError *error = nil;
NSArray *siteResults = [context executeFetchRequest:fetchRequest error:&error]; NSArray *siteResults = [context executeFetchRequest:fetchRequest error:&error];
if (!siteResults) { if (!siteResults) {
err( @"While fetching elements for completion: %@", error ); err( @"While fetching sites for completion: %@", error );
return; return;
} }
[profiler finishJob:@"do fetch"]; [profiler finishJob:@"do fetch"];
NSMutableArray *newElements = [NSMutableArray arrayWithCapacity:[siteResults count]]; NSMutableArray *newSites = [NSMutableArray arrayWithCapacity:[siteResults count]];
for (MPSiteEntity *element in siteResults) for (MPSiteEntity *site in siteResults)
[newElements addObject:[[MPElementModel alloc] initWithEntity:element]]; [newSites addObject:[[MPSiteModel alloc] initWithEntity:site]];
[profiler finishJob:@"make models"]; [profiler finishJob:@"make models"];
self.elements = newElements; self.sites = newSites;
[profiler finishJob:@"update elements"]; [profiler finishJob:@"update sites"];
}]; }];
[profiler finishJob:@"done"]; [profiler finishJob:@"done"];
} }
@ -546,7 +546,7 @@
return; return;
} }
NSString *siteName = self.selectedElement.siteName; NSString *siteName = self.selectedSite.siteName;
if (!siteName) if (!siteName)
return; return;
@ -559,14 +559,14 @@
NSMakeRange( siteNameQueryRange.length, siteName.length - siteNameQueryRange.length ); NSMakeRange( siteNameQueryRange.length, siteName.length - siteNameQueryRange.length );
} }
[self.siteTable scrollRowToVisible:(NSInteger)self.elementsController.selectionIndex]; [self.siteTable scrollRowToVisible:(NSInteger)self.sitesController.selectionIndex];
[self updateGradient]; [self updateGradient];
} }
- (void)updateGradient { - (void)updateGradient {
NSView *siteScrollView = self.siteTable.superview.superview; NSView *siteScrollView = self.siteTable.superview.superview;
NSRect selectedCellFrame = [self.siteTable frameOfCellAtColumn:0 row:((NSInteger)self.elementsController.selectionIndex)]; NSRect selectedCellFrame = [self.siteTable frameOfCellAtColumn:0 row:((NSInteger)self.sitesController.selectionIndex)];
CGFloat selectedOffset = [siteScrollView convertPoint:selectedCellFrame.origin fromView:self.siteTable].y; CGFloat selectedOffset = [siteScrollView convertPoint:selectedCellFrame.origin fromView:self.siteTable].y;
CGFloat gradientOpacity = selectedOffset / siteScrollView.bounds.size.height; CGFloat gradientOpacity = selectedOffset / siteScrollView.bounds.size.height;
self.siteGradient.colors = @[ self.siteGradient.colors = @[
@ -597,7 +597,7 @@
} }
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *moc) { [MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *moc) {
[[self.selectedElement entityInContext:moc] use]; [[self.selectedSite entityInContext:moc] use];
[moc saveToStore]; [moc saveToStore];
}]; }];
} }

View File

@ -8,7 +8,7 @@
<customObject id="-2" userLabel="File's Owner" customClass="MPPasswordWindowController"> <customObject id="-2" userLabel="File's Owner" customClass="MPPasswordWindowController">
<connections> <connections>
<outlet property="blurView" destination="Bwc-sd-6gm" id="wNV-0x-LJn"/> <outlet property="blurView" destination="Bwc-sd-6gm" id="wNV-0x-LJn"/>
<outlet property="elementsController" destination="mcS-ik-b0n" id="cdF-BL-lfg"/> <outlet property="sitesController" destination="mcS-ik-b0n" id="cdF-BL-lfg"/>
<outlet property="inputLabel" destination="OnR-s6-d4P" id="p6G-Ut-cdu"/> <outlet property="inputLabel" destination="OnR-s6-d4P" id="p6G-Ut-cdu"/>
<outlet property="passwordTypesBox" destination="bZe-7q-i6q" id="Ai3-pt-i6K"/> <outlet property="passwordTypesBox" destination="bZe-7q-i6q" id="Ai3-pt-i6K"/>
<outlet property="passwordTypesMatrix" destination="3fr-Fd-pxx" id="T8g-mS-lxP"/> <outlet property="passwordTypesMatrix" destination="3fr-Fd-pxx" id="T8g-mS-lxP"/>
@ -144,7 +144,7 @@
<rect key="frame" x="0.0" y="0.0" width="512" height="147"/> <rect key="frame" x="0.0" y="0.0" width="512" height="147"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews> <subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" selectionHighlightStyle="sourceList" columnReordering="NO" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="33" rowSizeStyle="automatic" viewBased="YES" floatsGroupRows="NO" id="xvJ-5c-vDp" customClass="MPElementsTableView"> <tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" selectionHighlightStyle="sourceList" columnReordering="NO" columnResizing="NO" multipleSelection="NO" autosaveColumns="NO" rowHeight="33" rowSizeStyle="automatic" viewBased="YES" floatsGroupRows="NO" id="xvJ-5c-vDp" customClass="MPSitesTableView">
<rect key="frame" x="0.0" y="0.0" width="515" height="147"/> <rect key="frame" x="0.0" y="0.0" width="515" height="147"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<size key="intercellSpacing" width="3" height="2"/> <size key="intercellSpacing" width="3" height="2"/>
@ -262,7 +262,7 @@
<color key="backgroundColor" red="1" green="1" blue="1" alpha="0.0" colorSpace="calibratedRGB"/> <color key="backgroundColor" red="1" green="1" blue="1" alpha="0.0" colorSpace="calibratedRGB"/>
</searchFieldCell> </searchFieldCell>
<connections> <connections>
<action selector="doSearchElements:" target="-2" id="NJO-iR-OXt"/> <action selector="doSearchSites:" target="-2" id="NJO-iR-OXt"/>
<binding destination="-2" name="hidden" keyPath="locked" id="fAX-uK-cgn"/> <binding destination="-2" name="hidden" keyPath="locked" id="fAX-uK-cgn"/>
<outlet property="delegate" destination="-2" id="2WA-uI-asx"/> <outlet property="delegate" destination="-2" id="2WA-uI-asx"/>
</connections> </connections>
@ -371,7 +371,7 @@
<modifierMask key="keyEquivalentModifierMask" command="YES"/> <modifierMask key="keyEquivalentModifierMask" command="YES"/>
</buttonCell> </buttonCell>
<connections> <connections>
<action selector="deleteElement:" target="-2" id="mVT-O6-KfN"/> <action selector="deleteSite:" target="-2" id="mVT-O6-KfN"/>
<binding destination="mcS-ik-b0n" name="hidden" keyPath="canRemove" id="eqU-d2-XhQ"> <binding destination="mcS-ik-b0n" name="hidden" keyPath="canRemove" id="eqU-d2-XhQ">
<dictionary key="options"> <dictionary key="options">
<string key="NSValueTransformerName">NSNegateBoolean</string> <string key="NSValueTransformerName">NSNegateBoolean</string>
@ -869,9 +869,9 @@
</view> </view>
</window> </window>
<userDefaultsController representsSharedInstance="YES" id="yy2-3W-Ocj"/> <userDefaultsController representsSharedInstance="YES" id="yy2-3W-Ocj"/>
<arrayController objectClassName="MPElementModel" id="mcS-ik-b0n"> <arrayController objectClassName="MPSiteModel" id="mcS-ik-b0n">
<connections> <connections>
<binding destination="-2" name="contentArray" keyPath="elements" id="c96-Dv-HK1"/> <binding destination="-2" name="contentArray" keyPath="sites" id="c96-Dv-HK1"/>
</connections> </connections>
</arrayController> </arrayController>
<box autoresizesSubviews="NO" title="Password Types" borderType="line" titlePosition="noTitle" id="bZe-7q-i6q"> <box autoresizesSubviews="NO" title="Password Types" borderType="line" titlePosition="noTitle" id="bZe-7q-i6q">

View File

@ -9,8 +9,8 @@
*/ */
// //
// MPElementModel.h // MPSiteModel.h
// MPElementModel // MPSiteModel
// //
// Created by lhunath on 2/11/2014. // Created by lhunath on 2/11/2014.
// Copyright, lhunath (Maarten Billemont) 2014. All rights reserved. // Copyright, lhunath (Maarten Billemont) 2014. All rights reserved.
@ -19,7 +19,7 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
@class MPSiteEntity; @class MPSiteEntity;
@interface MPElementModel : NSObject @interface MPSiteModel : NSObject
@property (nonatomic) NSString *siteName; @property (nonatomic) NSString *siteName;
@property (nonatomic) MPSiteType type; @property (nonatomic) MPSiteType type;

View File

@ -9,21 +9,21 @@
*/ */
// //
// MPElementModel.h // MPSiteModel.h
// MPElementModel // MPSiteModel
// //
// Created by lhunath on 2/11/2014. // Created by lhunath on 2/11/2014.
// Copyright, lhunath (Maarten Billemont) 2014. All rights reserved. // Copyright, lhunath (Maarten Billemont) 2014. All rights reserved.
// //
#import "MPElementModel.h" #import "MPSiteModel.h"
#import "MPSiteEntity.h" #import "MPSiteEntity.h"
#import "MPEntities.h" #import "MPEntities.h"
#import "MPAppDelegate_Shared.h" #import "MPAppDelegate_Shared.h"
#import "MPAppDelegate_Store.h" #import "MPAppDelegate_Store.h"
#import "MPMacAppDelegate.h" #import "MPMacAppDelegate.h"
@implementation MPElementModel { @implementation MPSiteModel {
NSManagedObjectID *_entityOID; NSManagedObjectID *_entityOID;
BOOL _initialized; BOOL _initialized;
} }
@ -52,7 +52,7 @@
self.type = entity.type; self.type = entity.type;
self.typeName = entity.typeName; self.typeName = entity.typeName;
self.uses = entity.uses_; self.uses = entity.uses_;
self.counter = [entity isKindOfClass:[MPElementGeneratedEntity class]]? [(MPElementGeneratedEntity *)entity counter]: 0; self.counter = [entity isKindOfClass:[MPGeneratedSiteEntity class]]? [(MPGeneratedSiteEntity *)entity counter]: 0;
// Find all password types and the index of the current type amongst them. // Find all password types and the index of the current type amongst them.
[self updateContent:entity]; [self updateContent:entity];
@ -66,7 +66,7 @@
NSError *error; NSError *error;
MPSiteEntity *entity = (MPSiteEntity *)[moc existingObjectWithID:_entityOID error:&error]; MPSiteEntity *entity = (MPSiteEntity *)[moc existingObjectWithID:_entityOID error:&error];
if (!entity) if (!entity)
err( @"Couldn't retrieve active element: %@", error ); err( @"Couldn't retrieve active site: %@", error );
return entity; return entity;
} }
@ -83,8 +83,8 @@
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPSiteEntity *entity = [self entityInContext:context]; MPSiteEntity *entity = [self entityInContext:context];
if ([entity isKindOfClass:[MPElementGeneratedEntity class]]) { if ([entity isKindOfClass:[MPGeneratedSiteEntity class]]) {
((MPElementGeneratedEntity *)entity).counter = counter; ((MPGeneratedSiteEntity *)entity).counter = counter;
[context saveToStore]; [context saveToStore];
[self updateContent:entity]; [self updateContent:entity];

View File

@ -9,8 +9,8 @@
*/ */
// //
// MPElementsTableView.h // MPSitesTableView.h
// MPElementsTableView // MPSitesTableView
// //
// Created by lhunath on 2014-06-30. // Created by lhunath on 2014-06-30.
// Copyright, lhunath (Maarten Billemont) 2014. All rights reserved. // Copyright, lhunath (Maarten Billemont) 2014. All rights reserved.
@ -20,7 +20,7 @@
@class MPPasswordWindowController; @class MPPasswordWindowController;
@interface MPElementsTableView : NSTableView @interface MPSitesTableView : NSTableView
@property(nonatomic, weak) MPPasswordWindowController *controller; @property(nonatomic, weak) MPPasswordWindowController *controller;

View File

@ -9,17 +9,17 @@
*/ */
// //
// MPElementsTableView.h // MPSitesTableView.h
// MPElementsTableView // MPSitesTableView
// //
// Created by lhunath on 2014-06-30. // Created by lhunath on 2014-06-30.
// Copyright, lhunath (Maarten Billemont) 2014. All rights reserved. // Copyright, lhunath (Maarten Billemont) 2014. All rights reserved.
// //
#import "MPElementsTableView.h" #import "MPSitesTableView.h"
#import "MPPasswordWindowController.h" #import "MPPasswordWindowController.h"
@implementation MPElementsTableView @implementation MPSitesTableView
- (void)doCommandBySelector:(SEL)aSelector { - (void)doCommandBySelector:(SEL)aSelector {

View File

@ -9,12 +9,12 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
93D390C676DF52DA7E459F19 /* MPPasswordWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39D9D0061FF1159998F06 /* MPPasswordWindow.m */; }; 93D390C676DF52DA7E459F19 /* MPPasswordWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39D9D0061FF1159998F06 /* MPPasswordWindow.m */; };
93D392EC39DA43C46C692C12 /* NSDictionary+Indexing.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D393B97158D7BE9332EA53 /* NSDictionary+Indexing.h */; }; 93D392EC39DA43C46C692C12 /* NSDictionary+Indexing.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D393B97158D7BE9332EA53 /* NSDictionary+Indexing.h */; };
93D394C4254EEB45FB335AFB /* MPElementsTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39423D7BF4FD31FE6D27C /* MPElementsTableView.m */; }; 93D394C4254EEB45FB335AFB /* MPSitesTableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39423D7BF4FD31FE6D27C /* MPSitesTableView.m */; };
93D395F08A087F8A24689347 /* NSArray+Indexing.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */; }; 93D395F08A087F8A24689347 /* NSArray+Indexing.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */; };
93D3970BCF85F7902E611168 /* PearlProfiler.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39DB3A8ADED08C39A6228 /* PearlProfiler.m */; }; 93D3970BCF85F7902E611168 /* PearlProfiler.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39DB3A8ADED08C39A6228 /* PearlProfiler.m */; };
93D39784E725A34D1EE3FB3B /* MPInitialWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39D3CB30874147D9A9E1B /* MPInitialWindowController.m */; }; 93D39784E725A34D1EE3FB3B /* MPInitialWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39D3CB30874147D9A9E1B /* MPInitialWindowController.m */; };
93D39C34FE35830EF5BE1D2A /* NSArray+Indexing.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D396D04E57792A54D437AC /* NSArray+Indexing.h */; }; 93D39C34FE35830EF5BE1D2A /* NSArray+Indexing.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D396D04E57792A54D437AC /* NSArray+Indexing.h */; };
93D39C5789EFA607CF788082 /* MPElementModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39E73BF5CBF8E5B005CD3 /* MPElementModel.m */; }; 93D39C5789EFA607CF788082 /* MPSiteModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39E73BF5CBF8E5B005CD3 /* MPSiteModel.m */; };
93D39D304F73B3BBA031522A /* PearlProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D394EEFF5BF555A55AF361 /* PearlProfiler.h */; }; 93D39D304F73B3BBA031522A /* PearlProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 93D394EEFF5BF555A55AF361 /* PearlProfiler.h */; };
93D39E281E3658B30550CB55 /* NSDictionary+Indexing.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39AA1EE2E1E7B81372240 /* NSDictionary+Indexing.m */; }; 93D39E281E3658B30550CB55 /* NSDictionary+Indexing.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39AA1EE2E1E7B81372240 /* NSDictionary+Indexing.m */; };
93D39F833DEC1C89B2F795AC /* MPPasswordWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39A57A7823DE98A0FF83C /* MPPasswordWindowController.m */; }; 93D39F833DEC1C89B2F795AC /* MPPasswordWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 93D39A57A7823DE98A0FF83C /* MPPasswordWindowController.m */; };
@ -230,21 +230,21 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+Indexing.m"; sourceTree = "<group>"; }; 93D39067C0AFDC581794E2B8 /* NSArray+Indexing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+Indexing.m"; sourceTree = "<group>"; };
93D39240B5143E01F0B75E96 /* MPElementModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPElementModel.h; sourceTree = "<group>"; }; 93D39240B5143E01F0B75E96 /* MPSiteModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSiteModel.h; sourceTree = "<group>"; };
93D392C3918763B3B72CF366 /* MPPasswordWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPasswordWindowController.h; sourceTree = "<group>"; }; 93D392C3918763B3B72CF366 /* MPPasswordWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPasswordWindowController.h; sourceTree = "<group>"; };
93D39368EF3CBFEF2AFCA15A /* MPInitialWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPInitialWindowController.h; sourceTree = "<group>"; }; 93D39368EF3CBFEF2AFCA15A /* MPInitialWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPInitialWindowController.h; sourceTree = "<group>"; };
93D393B97158D7BE9332EA53 /* NSDictionary+Indexing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+Indexing.h"; sourceTree = "<group>"; }; 93D393B97158D7BE9332EA53 /* NSDictionary+Indexing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSDictionary+Indexing.h"; sourceTree = "<group>"; };
93D39423D7BF4FD31FE6D27C /* MPElementsTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPElementsTableView.m; sourceTree = "<group>"; }; 93D39423D7BF4FD31FE6D27C /* MPSitesTableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPSitesTableView.m; sourceTree = "<group>"; };
93D394EEFF5BF555A55AF361 /* PearlProfiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PearlProfiler.h; path = ../../../External/Pearl/Pearl/PearlProfiler.h; sourceTree = "<group>"; }; 93D394EEFF5BF555A55AF361 /* PearlProfiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PearlProfiler.h; path = ../../../External/Pearl/Pearl/PearlProfiler.h; sourceTree = "<group>"; };
93D396D04E57792A54D437AC /* NSArray+Indexing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+Indexing.h"; sourceTree = "<group>"; }; 93D396D04E57792A54D437AC /* NSArray+Indexing.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+Indexing.h"; sourceTree = "<group>"; };
93D3977484534E99F9BA579D /* MPPasswordWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPasswordWindow.h; sourceTree = "<group>"; }; 93D3977484534E99F9BA579D /* MPPasswordWindow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPPasswordWindow.h; sourceTree = "<group>"; };
93D39A57A7823DE98A0FF83C /* MPPasswordWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPPasswordWindowController.m; sourceTree = "<group>"; }; 93D39A57A7823DE98A0FF83C /* MPPasswordWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPPasswordWindowController.m; sourceTree = "<group>"; };
93D39AA1EE2E1E7B81372240 /* NSDictionary+Indexing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+Indexing.m"; sourceTree = "<group>"; }; 93D39AA1EE2E1E7B81372240 /* NSDictionary+Indexing.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSDictionary+Indexing.m"; sourceTree = "<group>"; };
93D39AC6360DDC16AEAA4119 /* MPElementsTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPElementsTableView.h; sourceTree = "<group>"; }; 93D39AC6360DDC16AEAA4119 /* MPSitesTableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPSitesTableView.h; sourceTree = "<group>"; };
93D39D3CB30874147D9A9E1B /* MPInitialWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPInitialWindowController.m; sourceTree = "<group>"; }; 93D39D3CB30874147D9A9E1B /* MPInitialWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPInitialWindowController.m; sourceTree = "<group>"; };
93D39D9D0061FF1159998F06 /* MPPasswordWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPPasswordWindow.m; sourceTree = "<group>"; }; 93D39D9D0061FF1159998F06 /* MPPasswordWindow.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPPasswordWindow.m; sourceTree = "<group>"; };
93D39DB3A8ADED08C39A6228 /* PearlProfiler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PearlProfiler.m; path = ../../../External/Pearl/Pearl/PearlProfiler.m; sourceTree = "<group>"; }; 93D39DB3A8ADED08C39A6228 /* PearlProfiler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = PearlProfiler.m; path = ../../../External/Pearl/Pearl/PearlProfiler.m; sourceTree = "<group>"; };
93D39E73BF5CBF8E5B005CD3 /* MPElementModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPElementModel.m; sourceTree = "<group>"; }; 93D39E73BF5CBF8E5B005CD3 /* MPSiteModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPSiteModel.m; sourceTree = "<group>"; };
DA0933C91747A56A00DE1CEF /* MPInitialWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MPInitialWindow.xib; sourceTree = "<group>"; }; DA0933C91747A56A00DE1CEF /* MPInitialWindow.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MPInitialWindow.xib; sourceTree = "<group>"; };
DA0933CB1747AD2D00DE1CEF /* shot-laptop-leaning-iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shot-laptop-leaning-iphone.png"; sourceTree = "<group>"; }; DA0933CB1747AD2D00DE1CEF /* shot-laptop-leaning-iphone.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "shot-laptop-leaning-iphone.png"; sourceTree = "<group>"; };
DA0933CF1747B91B00DE1CEF /* appstore.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = appstore.png; sourceTree = "<group>"; }; DA0933CF1747B91B00DE1CEF /* appstore.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = appstore.png; sourceTree = "<group>"; };
@ -1051,8 +1051,8 @@
DA5E5CC41724A667003798D8 /* MainMenu.xib */, DA5E5CC41724A667003798D8 /* MainMenu.xib */,
DA5E5CC61724A667003798D8 /* main.m */, DA5E5CC61724A667003798D8 /* main.m */,
DA0933C91747A56A00DE1CEF /* MPInitialWindow.xib */, DA0933C91747A56A00DE1CEF /* MPInitialWindow.xib */,
93D39E73BF5CBF8E5B005CD3 /* MPElementModel.m */, 93D39E73BF5CBF8E5B005CD3 /* MPSiteModel.m */,
93D39240B5143E01F0B75E96 /* MPElementModel.h */, 93D39240B5143E01F0B75E96 /* MPSiteModel.h */,
DA2508F019511D3600AC23F1 /* MPPasswordWindowController.xib */, DA2508F019511D3600AC23F1 /* MPPasswordWindowController.xib */,
93D39A57A7823DE98A0FF83C /* MPPasswordWindowController.m */, 93D39A57A7823DE98A0FF83C /* MPPasswordWindowController.m */,
93D392C3918763B3B72CF366 /* MPPasswordWindowController.h */, 93D392C3918763B3B72CF366 /* MPPasswordWindowController.h */,
@ -1060,8 +1060,8 @@
93D3977484534E99F9BA579D /* MPPasswordWindow.h */, 93D3977484534E99F9BA579D /* MPPasswordWindow.h */,
93D39D3CB30874147D9A9E1B /* MPInitialWindowController.m */, 93D39D3CB30874147D9A9E1B /* MPInitialWindowController.m */,
93D39368EF3CBFEF2AFCA15A /* MPInitialWindowController.h */, 93D39368EF3CBFEF2AFCA15A /* MPInitialWindowController.h */,
93D39423D7BF4FD31FE6D27C /* MPElementsTableView.m */, 93D39423D7BF4FD31FE6D27C /* MPSitesTableView.m */,
93D39AC6360DDC16AEAA4119 /* MPElementsTableView.h */, 93D39AC6360DDC16AEAA4119 /* MPSitesTableView.h */,
); );
path = Mac; path = Mac;
sourceTree = "<group>"; sourceTree = "<group>";
@ -2159,13 +2159,13 @@
DA5E5D031724A667003798D8 /* MPMacAppDelegate.m in Sources */, DA5E5D031724A667003798D8 /* MPMacAppDelegate.m in Sources */,
DA5E5D041724A667003798D8 /* MPMacConfig.m in Sources */, DA5E5D041724A667003798D8 /* MPMacConfig.m in Sources */,
DA5E5D0C1724A667003798D8 /* main.m in Sources */, DA5E5D0C1724A667003798D8 /* main.m in Sources */,
93D39C5789EFA607CF788082 /* MPElementModel.m in Sources */, 93D39C5789EFA607CF788082 /* MPSiteModel.m in Sources */,
93D39F833DEC1C89B2F795AC /* MPPasswordWindowController.m in Sources */, 93D39F833DEC1C89B2F795AC /* MPPasswordWindowController.m in Sources */,
DA32CFD919CF1C70004F3F0E /* MPGeneratedSiteEntity.m in Sources */, DA32CFD919CF1C70004F3F0E /* MPGeneratedSiteEntity.m in Sources */,
93D390C676DF52DA7E459F19 /* MPPasswordWindow.m in Sources */, 93D390C676DF52DA7E459F19 /* MPPasswordWindow.m in Sources */,
93D39784E725A34D1EE3FB3B /* MPInitialWindowController.m in Sources */, 93D39784E725A34D1EE3FB3B /* MPInitialWindowController.m in Sources */,
DA32CFDF19CF1C70004F3F0E /* MPSiteEntity.m in Sources */, DA32CFDF19CF1C70004F3F0E /* MPSiteEntity.m in Sources */,
93D394C4254EEB45FB335AFB /* MPElementsTableView.m in Sources */, 93D394C4254EEB45FB335AFB /* MPSitesTableView.m in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

View File

@ -8,10 +8,10 @@
<attribute name="uses_" attributeType="Integer 16" defaultValueString="0" syncable="YES"/> <attribute name="uses_" attributeType="Integer 16" defaultValueString="0" syncable="YES"/>
<relationship name="user" minCount="1" maxCount="1" deletionRule="Nullify" destinationEntity="MPUserEntity" inverseName="elements" inverseEntity="MPUserEntity" elementID="FC8AE32E-7BE3-4FA6-8611-B7DC0DB063EF" syncable="YES"/> <relationship name="user" minCount="1" maxCount="1" deletionRule="Nullify" destinationEntity="MPUserEntity" inverseName="elements" inverseEntity="MPUserEntity" elementID="FC8AE32E-7BE3-4FA6-8611-B7DC0DB063EF" syncable="YES"/>
</entity> </entity>
<entity name="MPElementGeneratedEntity" representedClassName="MPSiteGeneratedEntity" parentEntity="MPElementEntity" elementID="789304EA-070D-4982-8C20-54EECFC20CB6" syncable="YES"> <entity name="MPElementGeneratedEntity" representedClassName="MPGeneratedSiteEntity" parentEntity="MPElementEntity" elementID="789304EA-070D-4982-8C20-54EECFC20CB6" syncable="YES">
<attribute name="counter_" optional="YES" attributeType="Integer 32" defaultValueString="1" syncable="YES"/> <attribute name="counter_" optional="YES" attributeType="Integer 32" defaultValueString="1" syncable="YES"/>
</entity> </entity>
<entity name="MPElementStoredEntity" representedClassName="MPSiteStoredEntity" parentEntity="MPElementEntity" elementID="BEEF1688-0CCD-4699-A86A-4D860FE2CEB8" syncable="YES"> <entity name="MPElementStoredEntity" representedClassName="MPStoredSiteEntity" parentEntity="MPElementEntity" elementID="BEEF1688-0CCD-4699-A86A-4D860FE2CEB8" syncable="YES">
<attribute name="contentObject" optional="YES" attributeType="Transformable" storedInTruthFile="YES" syncable="YES"/> <attribute name="contentObject" optional="YES" attributeType="Transformable" storedInTruthFile="YES" syncable="YES"/>
</entity> </entity>
<entity name="MPUserEntity" representedClassName="MPUserEntity" elementID="D18D6772-040E-4CFE-8F32-A34B08E9E9BC" syncable="YES"> <entity name="MPUserEntity" representedClassName="MPUserEntity" elementID="D18D6772-040E-4CFE-8F32-A34B08E9E9BC" syncable="YES">

View File

@ -13,10 +13,10 @@
<attribute name="version_" attributeType="Integer 16" minValueString="0" defaultValueString="0" syncable="YES"/> <attribute name="version_" attributeType="Integer 16" minValueString="0" defaultValueString="0" syncable="YES"/>
<relationship name="user" minCount="1" maxCount="1" deletionRule="Nullify" destinationEntity="MPUserEntity" inverseName="elements" inverseEntity="MPUserEntity" elementID="FC8AE32E-7BE3-4FA6-8611-B7DC0DB063EF" syncable="YES"/> <relationship name="user" minCount="1" maxCount="1" deletionRule="Nullify" destinationEntity="MPUserEntity" inverseName="elements" inverseEntity="MPUserEntity" elementID="FC8AE32E-7BE3-4FA6-8611-B7DC0DB063EF" syncable="YES"/>
</entity> </entity>
<entity name="MPElementGeneratedEntity" representedClassName="MPSiteGeneratedEntity" parentEntity="MPElementEntity" elementID="789304EA-070D-4982-8C20-54EECFC20CB6" syncable="YES"> <entity name="MPElementGeneratedEntity" representedClassName="MPGeneratedSiteEntity" parentEntity="MPElementEntity" elementID="789304EA-070D-4982-8C20-54EECFC20CB6" syncable="YES">
<attribute name="counter_" optional="YES" attributeType="Integer 32" defaultValueString="1" syncable="YES"/> <attribute name="counter_" optional="YES" attributeType="Integer 32" defaultValueString="1" syncable="YES"/>
</entity> </entity>
<entity name="MPElementStoredEntity" representedClassName="MPSiteStoredEntity" parentEntity="MPElementEntity" elementID="BEEF1688-0CCD-4699-A86A-4D860FE2CEB8" syncable="YES"> <entity name="MPElementStoredEntity" representedClassName="MPStoredSiteEntity" parentEntity="MPElementEntity" elementID="BEEF1688-0CCD-4699-A86A-4D860FE2CEB8" syncable="YES">
<attribute name="contentObject" optional="YES" attributeType="Transformable" storedInTruthFile="YES" syncable="YES"/> <attribute name="contentObject" optional="YES" attributeType="Transformable" storedInTruthFile="YES" syncable="YES"/>
</entity> </entity>
<entity name="MPUserEntity" representedClassName="MPUserEntity" elementID="D18D6772-040E-4CFE-8F32-A34B08E9E9BC" syncable="YES"> <entity name="MPUserEntity" representedClassName="MPUserEntity" elementID="D18D6772-040E-4CFE-8F32-A34B08E9E9BC" syncable="YES">

View File

@ -13,10 +13,10 @@
<attribute name="version_" attributeType="Integer 16" minValueString="0" defaultValueString="0" syncable="YES"/> <attribute name="version_" attributeType="Integer 16" minValueString="0" defaultValueString="0" syncable="YES"/>
<relationship name="user" minCount="1" maxCount="1" deletionRule="Nullify" destinationEntity="MPUserEntity" inverseName="elements" inverseEntity="MPUserEntity" elementID="FC8AE32E-7BE3-4FA6-8611-B7DC0DB063EF" syncable="YES"/> <relationship name="user" minCount="1" maxCount="1" deletionRule="Nullify" destinationEntity="MPUserEntity" inverseName="elements" inverseEntity="MPUserEntity" elementID="FC8AE32E-7BE3-4FA6-8611-B7DC0DB063EF" syncable="YES"/>
</entity> </entity>
<entity name="MPElementGeneratedEntity" representedClassName="MPSiteGeneratedEntity" parentEntity="MPElementEntity" elementID="789304EA-070D-4982-8C20-54EECFC20CB6" syncable="YES"> <entity name="MPElementGeneratedEntity" representedClassName="MPGeneratedSiteEntity" parentEntity="MPElementEntity" elementID="789304EA-070D-4982-8C20-54EECFC20CB6" syncable="YES">
<attribute name="counter_" optional="YES" attributeType="Integer 32" defaultValueString="1" syncable="YES"/> <attribute name="counter_" optional="YES" attributeType="Integer 32" defaultValueString="1" syncable="YES"/>
</entity> </entity>
<entity name="MPElementStoredEntity" representedClassName="MPSiteStoredEntity" parentEntity="MPElementEntity" elementID="BEEF1688-0CCD-4699-A86A-4D860FE2CEB8" syncable="YES"> <entity name="MPElementStoredEntity" representedClassName="MPStoredSiteEntity" parentEntity="MPElementEntity" elementID="BEEF1688-0CCD-4699-A86A-4D860FE2CEB8" syncable="YES">
<attribute name="contentObject" optional="YES" attributeType="Transformable" storedInTruthFile="YES" syncable="YES"/> <attribute name="contentObject" optional="YES" attributeType="Transformable" storedInTruthFile="YES" syncable="YES"/>
</entity> </entity>
<entity name="MPUserEntity" representedClassName="MPUserEntity" syncable="YES"> <entity name="MPUserEntity" representedClassName="MPUserEntity" syncable="YES">

View File

@ -13,10 +13,10 @@
<attribute name="version_" attributeType="Integer 16" minValueString="0" defaultValueString="0" syncable="YES"/> <attribute name="version_" attributeType="Integer 16" minValueString="0" defaultValueString="0" syncable="YES"/>
<relationship name="user" minCount="1" maxCount="1" deletionRule="Nullify" destinationEntity="MPUserEntity" inverseName="elements" inverseEntity="MPUserEntity" elementID="FC8AE32E-7BE3-4FA6-8611-B7DC0DB063EF" syncable="YES"/> <relationship name="user" minCount="1" maxCount="1" deletionRule="Nullify" destinationEntity="MPUserEntity" inverseName="elements" inverseEntity="MPUserEntity" elementID="FC8AE32E-7BE3-4FA6-8611-B7DC0DB063EF" syncable="YES"/>
</entity> </entity>
<entity name="MPElementGeneratedEntity" representedClassName="MPSiteGeneratedEntity" parentEntity="MPElementEntity" elementID="789304EA-070D-4982-8C20-54EECFC20CB6" syncable="YES"> <entity name="MPElementGeneratedEntity" representedClassName="MPGeneratedSiteEntity" parentEntity="MPElementEntity" elementID="789304EA-070D-4982-8C20-54EECFC20CB6" syncable="YES">
<attribute name="counter_" optional="YES" attributeType="Integer 32" defaultValueString="1" syncable="YES"/> <attribute name="counter_" optional="YES" attributeType="Integer 32" defaultValueString="1" syncable="YES"/>
</entity> </entity>
<entity name="MPElementStoredEntity" representedClassName="MPSiteStoredEntity" parentEntity="MPElementEntity" elementID="BEEF1688-0CCD-4699-A86A-4D860FE2CEB8" syncable="YES"> <entity name="MPElementStoredEntity" representedClassName="MPStoredSiteEntity" parentEntity="MPElementEntity" elementID="BEEF1688-0CCD-4699-A86A-4D860FE2CEB8" syncable="YES">
<attribute name="contentObject" optional="YES" attributeType="Transformable" storedInTruthFile="YES" syncable="YES"/> <attribute name="contentObject" optional="YES" attributeType="Transformable" storedInTruthFile="YES" syncable="YES"/>
</entity> </entity>
<entity name="MPUserEntity" representedClassName="MPUserEntity" syncable="YES"> <entity name="MPUserEntity" representedClassName="MPUserEntity" syncable="YES">

View File

@ -27,7 +27,7 @@ typedef NS_ENUM ( NSUInteger, MPPasswordCellMode ) {
@interface MPPasswordCell : MPCell <UIScrollViewDelegate, UITextFieldDelegate> @interface MPPasswordCell : MPCell <UIScrollViewDelegate, UITextFieldDelegate>
- (void)setElement:(MPSiteEntity *)element animated:(BOOL)animated; - (void)setSite:(MPSiteEntity *)site animated:(BOOL)animated;
- (void)setTransientSite:(NSString *)siteName animated:(BOOL)animated; - (void)setTransientSite:(NSString *)siteName animated:(BOOL)animated;
- (void)setMode:(MPPasswordCellMode)mode animated:(BOOL)animated; - (void)setMode:(MPPasswordCellMode)mode animated:(BOOL)animated;

View File

@ -45,7 +45,7 @@
@end @end
@implementation MPPasswordCell { @implementation MPPasswordCell {
NSManagedObjectID *_elementOID; NSManagedObjectID *_siteOID;
} }
#pragma mark - Life cycle #pragma mark - Life cycle
@ -132,7 +132,7 @@
[super prepareForReuse]; [super prepareForReuse];
_elementOID = nil; _siteOID = nil;
self.transientSite = nil; self.transientSite = nil;
self.mode = MPPasswordCellModePassword; self.mode = MPPasswordCellModePassword;
[self updateAnimated:NO]; [self updateAnimated:NO];
@ -155,9 +155,9 @@
[self updateAnimated:animated]; [self updateAnimated:animated];
} }
- (void)setElement:(MPSiteEntity *)element animated:(BOOL)animated { - (void)setSite:(MPSiteEntity *)site animated:(BOOL)animated {
_elementOID = [element objectID]; _siteOID = [site objectID];
[self updateAnimated:animated]; [self updateAnimated:animated];
} }
@ -195,10 +195,10 @@
NSString *password = self.passwordField.text; NSString *password = self.passwordField.text;
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
TimeToCrack timeToCrack; TimeToCrack timeToCrack;
MPSiteEntity *element = [self elementInContext:context]; MPSiteEntity *site = [self siteInContext:context];
id<MPAlgorithm> algorithm = element.algorithm?: MPAlgorithmDefault; id<MPAlgorithm> algorithm = site.algorithm?: MPAlgorithmDefault;
MPAttacker attackHardware = [[MPConfig get].siteAttacker unsignedIntegerValue]; MPAttacker attackHardware = [[MPConfig get].siteAttacker unsignedIntegerValue];
if ([algorithm timeToCrack:&timeToCrack passwordOfType:[self elementInContext:context].type byAttacker:attackHardware] || if ([algorithm timeToCrack:&timeToCrack passwordOfType:[self siteInContext:context].type byAttacker:attackHardware] ||
[algorithm timeToCrack:&timeToCrack passwordString:password byAttacker:attackHardware]) [algorithm timeToCrack:&timeToCrack passwordString:password byAttacker:attackHardware])
PearlMainQueue( ^{ PearlMainQueue( ^{
self.strengthLabel.text = NSStringFromTimeToCrack( timeToCrack ); self.strengthLabel.text = NSStringFromTimeToCrack( timeToCrack );
@ -214,19 +214,19 @@
NSString *text = textField.text; NSString *text = textField.text;
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPSiteEntity *element = [self elementInContext:context]; MPSiteEntity *site = [self siteInContext:context];
if (!element) if (!site)
return; return;
if (textField == self.passwordField) { if (textField == self.passwordField) {
if ([element.algorithm savePassword:text toSite:element usingKey:[MPiOSAppDelegate get].key]) if ([site.algorithm savePassword:text toSite:site usingKey:[MPiOSAppDelegate get].key])
[PearlOverlay showTemporaryOverlayWithTitle:@"Password Updated" dismissAfter:2]; [PearlOverlay showTemporaryOverlayWithTitle:@"Password Updated" dismissAfter:2];
} }
else if (textField == self.loginNameField && else if (textField == self.loginNameField &&
((element.loginGenerated && ![text length]) || ((site.loginGenerated && ![text length]) ||
(!element.loginGenerated && ![text isEqualToString:element.loginName]))) { (!site.loginGenerated && ![text isEqualToString:site.loginName]))) {
element.loginName = text; site.loginName = text;
element.loginGenerated = NO; site.loginGenerated = NO;
if ([text length]) if ([text length])
[PearlOverlay showTemporaryOverlayWithTitle:@"Login Name Saved" dismissAfter:2]; [PearlOverlay showTemporaryOverlayWithTitle:@"Login Name Saved" dismissAfter:2];
else else
@ -243,17 +243,17 @@
- (IBAction)doDelete:(UIButton *)sender { - (IBAction)doDelete:(UIButton *)sender {
MPSiteEntity *element = [self elementInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]]; MPSiteEntity *site = [self siteInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]];
if (!element) if (!site)
return; return;
[PearlSheet showSheetWithTitle:strf( @"Delete %@?", element.name ) viewStyle:UIActionSheetStyleAutomatic [PearlSheet showSheetWithTitle:strf( @"Delete %@?", site.name ) viewStyle:UIActionSheetStyleAutomatic
initSheet:nil tappedButtonBlock:^(UIActionSheet *sheet, NSInteger buttonIndex) { initSheet:nil tappedButtonBlock:^(UIActionSheet *sheet, NSInteger buttonIndex) {
if (buttonIndex == [sheet cancelButtonIndex]) if (buttonIndex == [sheet cancelButtonIndex])
return; return;
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
[context deleteObject:[self elementInContext:context]]; [context deleteObject:[self siteInContext:context]];
[context saveToStore]; [context saveToStore];
}]; }];
} cancelTitle:@"Cancel" destructiveTitle:@"Delete Site" otherTitles:nil]; } cancelTitle:@"Cancel" destructiveTitle:@"Delete Site" otherTitles:nil];
@ -265,12 +265,11 @@
[PearlSheet showSheetWithTitle:@"Change Password Type" viewStyle:UIActionSheetStyleAutomatic [PearlSheet showSheetWithTitle:@"Change Password Type" viewStyle:UIActionSheetStyleAutomatic
initSheet:^(UIActionSheet *sheet) { initSheet:^(UIActionSheet *sheet) {
MPSiteEntity MPSiteEntity *mainSite = [self siteInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]];
*mainElement = [self elementInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]];
for (NSNumber *typeNumber in [MPAlgorithmDefault allTypes]) { for (NSNumber *typeNumber in [MPAlgorithmDefault allTypes]) {
MPSiteType type = [typeNumber unsignedIntegerValue]; MPSiteType type = [typeNumber unsignedIntegerValue];
NSString *typeName = [MPAlgorithmDefault nameOfType:type]; NSString *typeName = [MPAlgorithmDefault nameOfType:type];
if (type == mainElement.type) if (type == mainSite.type)
[sheet addButtonWithTitle:strf( @"● %@", typeName )]; [sheet addButtonWithTitle:strf( @"● %@", typeName )];
else else
[sheet addButtonWithTitle:typeName]; [sheet addButtonWithTitle:typeName];
@ -282,9 +281,9 @@
MPSiteType type = [[MPAlgorithmDefault allTypes][buttonIndex] unsignedIntegerValue]?: MPSiteTypeGeneratedLong; MPSiteType type = [[MPAlgorithmDefault allTypes][buttonIndex] unsignedIntegerValue]?: MPSiteTypeGeneratedLong;
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPSiteEntity *element = [self elementInContext:context]; MPSiteEntity *site = [self siteInContext:context];
element = [[MPiOSAppDelegate get] changeSite:element saveInContext:context toType:type]; site = [[MPiOSAppDelegate get] changeSite:site saveInContext:context toType:type];
[self setElement:element animated:YES]; [self setSite:site animated:YES];
}]; }];
} cancelTitle:@"Cancel" destructiveTitle:nil otherTitles:nil]; } cancelTitle:@"Cancel" destructiveTitle:nil otherTitles:nil];
} }
@ -294,7 +293,7 @@
self.loginNameField.enabled = YES; self.loginNameField.enabled = YES;
self.passwordField.enabled = YES; self.passwordField.enabled = YES;
if ([self elementInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]].type & MPSiteTypeClassStored) if ([self siteInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]].type & MPSiteTypeClassStored)
[self.passwordField becomeFirstResponder]; [self.passwordField becomeFirstResponder];
else else
[self.loginNameField becomeFirstResponder]; [self.loginNameField becomeFirstResponder];
@ -317,7 +316,7 @@
- (IBAction)doUpgrade:(UIButton *)sender { - (IBAction)doUpgrade:(UIButton *)sender {
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
if (![[self elementInContext:context] migrateExplicitly:YES]) { if (![[self siteInContext:context] migrateExplicitly:YES]) {
[PearlOverlay showTemporaryOverlayWithTitle:@"Couldn't Upgrade Site" dismissAfter:2]; [PearlOverlay showTemporaryOverlayWithTitle:@"Couldn't Upgrade Site" dismissAfter:2];
return; return;
} }
@ -331,11 +330,11 @@
- (IBAction)doIncrementCounter:(UIButton *)sender { - (IBAction)doIncrementCounter:(UIButton *)sender {
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPSiteEntity *element = [self elementInContext:context]; MPSiteEntity *site = [self siteInContext:context];
if (!element || ![element isKindOfClass:[MPElementGeneratedEntity class]]) if (!site || ![site isKindOfClass:[MPGeneratedSiteEntity class]])
return; return;
++((MPElementGeneratedEntity *)element).counter; ++((MPGeneratedSiteEntity *)site).counter;
[context saveToStore]; [context saveToStore];
[PearlOverlay showTemporaryOverlayWithTitle:@"Generating New Password" dismissAfter:2]; [PearlOverlay showTemporaryOverlayWithTitle:@"Generating New Password" dismissAfter:2];
@ -363,11 +362,11 @@
return; return;
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPSiteEntity *element = [self elementInContext:context]; MPSiteEntity *site = [self siteInContext:context];
if (!element || ![element isKindOfClass:[MPElementGeneratedEntity class]]) if (!site || ![site isKindOfClass:[MPGeneratedSiteEntity class]])
return; return;
((MPElementGeneratedEntity *)element).counter = 1; ((MPGeneratedSiteEntity *)site).counter = 1;
[context saveToStore]; [context saveToStore];
[PearlOverlay showTemporaryOverlayWithTitle:@"Counter Reset" dismissAfter:2]; [PearlOverlay showTemporaryOverlayWithTitle:@"Counter Reset" dismissAfter:2];
@ -393,8 +392,8 @@
} }
[[MPiOSAppDelegate get] [[MPiOSAppDelegate get]
addSiteNamed:self.transientSite completion:^(MPSiteEntity *element, NSManagedObjectContext *context) { addSiteNamed:self.transientSite completion:^(MPSiteEntity *site, NSManagedObjectContext *context) {
[self copyContentOfElement:element saveInContext:context]; [self copyContentOfSite:site saveInContext:context];
PearlMainQueueAfter( .3f, ^{ PearlMainQueueAfter( .3f, ^{
[UIView animateWithDuration:.2f animations:^{ [UIView animateWithDuration:.2f animations:^{
@ -407,7 +406,7 @@
} }
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
[self copyContentOfElement:[self elementInContext:context] saveInContext:context]; [self copyContentOfSite:[self siteInContext:context] saveInContext:context];
PearlMainQueueAfter( .3f, ^{ PearlMainQueueAfter( .3f, ^{
[UIView animateWithDuration:.2f animations:^{ [UIView animateWithDuration:.2f animations:^{
@ -424,9 +423,9 @@
}]; }];
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPSiteEntity *element = [self elementInContext:context]; MPSiteEntity *site = [self siteInContext:context];
if (![self copyLoginOfElement:element saveInContext:context]) { if (![self copyLoginOfSite:site saveInContext:context]) {
element.loginGenerated = YES; site.loginGenerated = YES;
[context saveToStore]; [context saveToStore];
[PearlOverlay showTemporaryOverlayWithTitle:@"Login Name Generated" dismissAfter:2]; [PearlOverlay showTemporaryOverlayWithTitle:@"Login Name Generated" dismissAfter:2];
[self updateAnimated:YES]; [self updateAnimated:YES];
@ -462,15 +461,15 @@
} }
[UIView animateWithDuration:animated? .3f: 0 animations:^{ [UIView animateWithDuration:animated? .3f: 0 animations:^{
MPSiteEntity *mainElement = [self elementInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]]; MPSiteEntity *mainSite = [self siteInContext:[MPiOSAppDelegate managedObjectContextForMainThreadIfReady]];
// UI // UI
self.upgradeButton.alpha = mainElement.requiresExplicitMigration? 1: 0; self.upgradeButton.alpha = mainSite.requiresExplicitMigration? 1: 0;
BOOL settingsMode = self.mode == MPPasswordCellModeSettings; BOOL settingsMode = self.mode == MPPasswordCellModeSettings;
self.loginNameContainer.alpha = settingsMode || mainElement.loginGenerated || [mainElement.loginName length]? 0.7f: 0; self.loginNameContainer.alpha = settingsMode || mainSite.loginGenerated || [mainSite.loginName length]? 0.7f: 0;
self.loginNameField.textColor = [UIColor colorWithHexString:mainElement.loginGenerated? @"5E636D": @"6D5E63"]; self.loginNameField.textColor = [UIColor colorWithHexString:mainSite.loginGenerated? @"5E636D": @"6D5E63"];
self.modeButton.alpha = self.transientSite? 0: settingsMode? 0.5f: 0.1f; self.modeButton.alpha = self.transientSite? 0: settingsMode? 0.5f: 0.1f;
self.counterLabel.alpha = self.counterButton.alpha = mainElement.type & MPSiteTypeClassGenerated? 0.5f: 0; self.counterLabel.alpha = self.counterButton.alpha = mainSite.type & MPSiteTypeClassGenerated? 0.5f: 0;
self.modeButton.selected = settingsMode; self.modeButton.selected = settingsMode;
self.strengthLabel.gone = !settingsMode; self.strengthLabel.gone = !settingsMode;
self.modeScrollView.scrollEnabled = !self.transientSite; self.modeScrollView.scrollEnabled = !self.transientSite;
@ -485,34 +484,34 @@
[self.loginNameButton setTitle:@"Tap the pencil to save a username" forState:UIControlStateNormal]; [self.loginNameButton setTitle:@"Tap the pencil to save a username" forState:UIControlStateNormal];
// Site Name // Site Name
self.siteNameLabel.text = strl( @"%@ - %@", self.transientSite?: mainElement.name, self.siteNameLabel.text = strl( @"%@ - %@", self.transientSite?: mainSite.name,
self.transientSite? @"Tap to create": [mainElement.algorithm shortNameOfType:mainElement.type] ); self.transientSite? @"Tap to create": [mainSite.algorithm shortNameOfType:mainSite.type] );
// Site Password // Site Password
self.passwordField.secureTextEntry = [[MPiOSConfig get].hidePasswords boolValue]; self.passwordField.secureTextEntry = [[MPiOSConfig get].hidePasswords boolValue];
self.passwordField.attributedPlaceholder = stra( self.passwordField.attributedPlaceholder = stra(
mainElement.type & MPSiteTypeClassStored? strl( @"No password" ): mainSite.type & MPSiteTypeClassStored? strl( @"No password" ):
mainElement.type & MPSiteTypeClassGenerated? strl( @"..." ): @"", @{ mainSite.type & MPSiteTypeClassGenerated? strl( @"..." ): @"", @{
NSForegroundColorAttributeName : [UIColor whiteColor] NSForegroundColorAttributeName : [UIColor whiteColor]
} ); } );
[MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) { [MPiOSAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPSiteEntity *element = [self elementInContext:context]; MPSiteEntity *site = [self siteInContext:context];
MPKey *key = [MPiOSAppDelegate get].key; MPKey *key = [MPiOSAppDelegate get].key;
NSString *password, *loginName = [element resolveLoginUsingKey:key]; NSString *password, *loginName = [site resolveLoginUsingKey:key];
if (self.transientSite) if (self.transientSite)
password = [MPAlgorithmDefault generatePasswordForSiteNamed:self.transientSite ofType: password = [MPAlgorithmDefault generatePasswordForSiteNamed:self.transientSite ofType:
[[MPiOSAppDelegate get] activeUserInContext:context].defaultType?: MPSiteTypeGeneratedLong [[MPiOSAppDelegate get] activeUserInContext:context].defaultType?: MPSiteTypeGeneratedLong
withCounter:1 usingKey:key]; withCounter:1 usingKey:key];
else if (element) else if (site)
password = [element resolvePasswordUsingKey:key]; password = [site resolvePasswordUsingKey:key];
else else
return; return;
TimeToCrack timeToCrack; TimeToCrack timeToCrack;
NSString *timeToCrackString = nil; NSString *timeToCrackString = nil;
id<MPAlgorithm> algorithm = element.algorithm?: MPAlgorithmDefault; id<MPAlgorithm> algorithm = site.algorithm?: MPAlgorithmDefault;
MPAttacker attackHardware = [[MPConfig get].siteAttacker unsignedIntegerValue]; MPAttacker attackHardware = [[MPConfig get].siteAttacker unsignedIntegerValue];
if ([algorithm timeToCrack:&timeToCrack passwordOfType:element.type byAttacker:attackHardware] || if ([algorithm timeToCrack:&timeToCrack passwordOfType:site.type byAttacker:attackHardware] ||
[algorithm timeToCrack:&timeToCrack passwordString:password byAttacker:attackHardware]) [algorithm timeToCrack:&timeToCrack passwordString:password byAttacker:attackHardware])
timeToCrackString = NSStringFromTimeToCrack( timeToCrack ); timeToCrackString = NSStringFromTimeToCrack( timeToCrack );
@ -538,8 +537,8 @@
}]; }];
// Site Counter // Site Counter
if ([mainElement isKindOfClass:[MPElementGeneratedEntity class]]) if ([mainSite isKindOfClass:[MPGeneratedSiteEntity class]])
self.counterLabel.text = strf( @"%lu", (unsigned long)((MPElementGeneratedEntity *)mainElement).counter ); self.counterLabel.text = strf( @"%lu", (unsigned long)((MPGeneratedSiteEntity *)mainSite).counter );
// Site Login Name // Site Login Name
self.loginNameField.enabled = self.passwordField.enabled = // self.loginNameField.enabled = self.passwordField.enabled = //
@ -549,10 +548,10 @@
}]; }];
} }
- (BOOL)copyContentOfElement:(MPSiteEntity *)element saveInContext:(NSManagedObjectContext *)context { - (BOOL)copyContentOfSite:(MPSiteEntity *)site saveInContext:(NSManagedObjectContext *)context {
inf( @"Copying password for: %@", element.name ); inf( @"Copying password for: %@", site.name );
NSString *password = [element resolvePasswordUsingKey:[MPAppDelegate_Shared get].key]; NSString *password = [site resolvePasswordUsingKey:[MPAppDelegate_Shared get].key];
if (![password length]) if (![password length])
return NO; return NO;
@ -561,15 +560,15 @@
[UIPasteboard generalPasteboard].string = password; [UIPasteboard generalPasteboard].string = password;
} ); } );
[element use]; [site use];
[context saveToStore]; [context saveToStore];
return YES; return YES;
} }
- (BOOL)copyLoginOfElement:(MPSiteEntity *)element saveInContext:(NSManagedObjectContext *)context { - (BOOL)copyLoginOfSite:(MPSiteEntity *)site saveInContext:(NSManagedObjectContext *)context {
inf( @"Copying login for: %@", element.name ); inf( @"Copying login for: %@", site.name );
NSString *loginName = [element.algorithm resolveLoginForSite:element usingKey:[MPiOSAppDelegate get].key]; NSString *loginName = [site.algorithm resolveLoginForSite:site usingKey:[MPiOSAppDelegate get].key];
if (![loginName length]) if (![loginName length])
return NO; return NO;
@ -578,14 +577,14 @@
[UIPasteboard generalPasteboard].string = loginName; [UIPasteboard generalPasteboard].string = loginName;
} ); } );
[element use]; [site use];
[context saveToStore]; [context saveToStore];
return YES; return YES;
} }
- (MPSiteEntity *)elementInContext:(NSManagedObjectContext *)context { - (MPSiteEntity *)siteInContext:(NSManagedObjectContext *)context {
return [MPSiteEntity existingObjectWithID:_elementOID inContext:context]; return [MPSiteEntity existingObjectWithID:_siteOID inContext:context];
} }
@end @end

View File

@ -131,7 +131,7 @@ referenceSizeForHeaderInSection:(NSInteger)section {
MPPasswordCell *cell = [MPPasswordCell dequeueCellFromCollectionView:collectionView indexPath:indexPath]; MPPasswordCell *cell = [MPPasswordCell dequeueCellFromCollectionView:collectionView indexPath:indexPath];
if (indexPath.item < ((id<NSFetchedResultsSectionInfo>)self.fetchedResultsController.sections[indexPath.section]).numberOfObjects) if (indexPath.item < ((id<NSFetchedResultsSectionInfo>)self.fetchedResultsController.sections[indexPath.section]).numberOfObjects)
[cell setElement:[self.fetchedResultsController objectAtIndexPath:indexPath] animated:NO]; [cell setSite:[self.fetchedResultsController objectAtIndexPath:indexPath] animated:NO];
else else
[cell setTransientSite:self.query animated:NO]; [cell setTransientSite:self.query animated:NO];
@ -384,7 +384,7 @@ referenceSizeForHeaderInSection:(NSInteger)section {
[NSPredicate predicateWithFormat:@"user == %@ AND name BEGINSWITH[cd] %@", activeUserOID, query]: [NSPredicate predicateWithFormat:@"user == %@ AND name BEGINSWITH[cd] %@", activeUserOID, query]:
[NSPredicate predicateWithFormat:@"user == %@", activeUserOID]; [NSPredicate predicateWithFormat:@"user == %@", activeUserOID];
if (![self.fetchedResultsController performFetch:&error]) if (![self.fetchedResultsController performFetch:&error])
err( @"Couldn't fetch elements: %@", error ); err( @"Couldn't fetch sites: %@", error );
[self.passwordCollectionView performBatchUpdates:^{ [self.passwordCollectionView performBatchUpdates:^{
[self fetchedItemsDidUpdate]; [self fetchedItemsDidUpdate];

View File

@ -17,7 +17,7 @@
- (MPSiteType)selectedType; - (MPSiteType)selectedType;
@optional @optional
- (MPSiteEntity *)selectedElement; - (MPSiteEntity *)selectedSite;
@end @end

View File

@ -63,21 +63,21 @@
UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath]; UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
MPSiteEntity *selectedElement = nil; MPSiteEntity *selectedSite = nil;
if ([self.delegate respondsToSelector:@selector(selectedElement)]) if ([self.delegate respondsToSelector:@selector( selectedSite )])
selectedElement = [self.delegate selectedElement]; selectedSite = [self.delegate selectedSite];
MPSiteType cellType = [self typeAtIndexPath:indexPath]; MPSiteType cellType = [self typeAtIndexPath:indexPath];
MPSiteType selectedType = selectedElement? selectedElement.type: [self.delegate selectedType]; MPSiteType selectedType = selectedSite? selectedSite.type: [self.delegate selectedType];
cell.selected = (selectedType == cellType); cell.selected = (selectedType == cellType);
if (cellType != (MPSiteType)NSNotFound && cellType & MPSiteTypeClassGenerated) { if (cellType != (MPSiteType)NSNotFound && cellType & MPSiteTypeClassGenerated) {
[(UITextField *)[cell viewWithTag:2] setText:@"..."]; [(UITextField *)[cell viewWithTag:2] setText:@"..."];
NSString *name = selectedElement.name; NSString *name = selectedSite.name;
NSUInteger counter = 0; NSUInteger counter = 0;
if ([selectedElement isKindOfClass:[MPElementGeneratedEntity class]]) if ([selectedSite isKindOfClass:[MPGeneratedSiteEntity class]])
counter = ((MPElementGeneratedEntity *)selectedElement).counter; counter = ((MPGeneratedSiteEntity *)selectedSite).counter;
dispatch_async( dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0 ), ^{ dispatch_async( dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0 ), ^{
NSString *typeContent = [MPAlgorithmDefault generatePasswordForSiteNamed:name ofType:cellType NSString *typeContent = [MPAlgorithmDefault generatePasswordForSiteNamed:name ofType:cellType
@ -129,7 +129,7 @@
return (MPSiteType)NSNotFound; return (MPSiteType)NSNotFound;
default: { default: {
Throw(@"Unsupported row: %ld, when selecting generated element type.", (long)indexPath.row); Throw(@"Unsupported row: %ld, when selecting generated site type.", (long)indexPath.row);
} }
} }
} }
@ -147,13 +147,13 @@
return (MPSiteType)NSNotFound; return (MPSiteType)NSNotFound;
default: { default: {
Throw(@"Unsupported row: %ld, when selecting stored element type.", (long)indexPath.row); Throw(@"Unsupported row: %ld, when selecting stored site type.", (long)indexPath.row);
} }
} }
} }
default: default:
Throw(@"Unsupported section: %ld, when selecting element type.", (long)indexPath.section); Throw(@"Unsupported section: %ld, when selecting site type.", (long)indexPath.section);
} }
} }