2
0

Make new site creation on Mac same as iOS.

[FIXED]     Unable to create a site that is a substring of an existing site.
This commit is contained in:
Maarten Billemont 2015-03-05 17:28:04 -05:00
parent ca8f14fd3e
commit a383d0eee7
4 changed files with 139 additions and 65 deletions

View File

@ -80,7 +80,7 @@ uint8_t const *mpw_scrypt(const size_t keySize, const char *secret, const uint8_
uint8_t const *mpw_hmac_sha256(const uint8_t *key, const size_t keySize, const uint8_t *salt, const size_t saltSize) {
uint8_t *const buffer = malloc(32);
uint8_t *const buffer = malloc( 32 );
if (!buffer)
return NULL;
@ -96,24 +96,29 @@ const char *mpw_idForBuf(const void *buf, size_t length) {
return mpw_hex( hash, 32 );
}
static char **mpw_hex_buf = NULL;
static unsigned int mpw_hex_buf_i = 0;
//static char **mpw_hex_buf = NULL;
//static unsigned int mpw_hex_buf_i = 0;
const char *mpw_hex(const void *buf, size_t length) {
if (!mpw_hex_buf) {
mpw_hex_buf = malloc( 10 * sizeof( char* ) );
for (uint8_t i = 0; i < 10; ++i)
mpw_hex_buf[i] = NULL;
}
mpw_hex_buf_i = (mpw_hex_buf_i + 1) % 10;
// FIXME
// if (!mpw_hex_buf) {
// mpw_hex_buf = malloc( 10 * sizeof( char * ) );
// for (uint8_t i = 0; i < 10; ++i)
// mpw_hex_buf[i] = NULL;
// }
// mpw_hex_buf_i = (mpw_hex_buf_i + 1) % 10;
//
// mpw_hex_buf[mpw_hex_buf_i] = realloc( mpw_hex_buf[mpw_hex_buf_i], length * 2 + 1 );
// for (size_t kH = 0; kH < length; kH++)
// sprintf( &(mpw_hex_buf[mpw_hex_buf_i][kH * 2]), "%02X", ((const uint8_t *)buf)[kH] );
mpw_hex_buf[mpw_hex_buf_i] = realloc( mpw_hex_buf[mpw_hex_buf_i], length * 2 + 1 );
for (size_t kH = 0; kH < length; kH++)
sprintf( &(mpw_hex_buf[mpw_hex_buf_i][kH * 2]), "%02X", ((const uint8_t *)buf)[kH] );
return mpw_hex_buf[mpw_hex_buf_i];
// return mpw_hex_buf[mpw_hex_buf_i];
return NULL;
}
const char *mpw_hex_l(uint32_t number) {
return mpw_hex( &number, sizeof( number ) );
}
@ -144,7 +149,8 @@ const char *mpw_identicon(const char *fullName, const char *masterPassword) {
const char *accessory[] = {
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" };
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""
};
uint8_t identiconSeed[32];
HMAC_SHA256_Buf( masterPassword, strlen( masterPassword ), fullName, strlen( fullName ), identiconSeed );
@ -206,8 +212,8 @@ const size_t mpw_charlen(const char *utf8String) {
size_t charlen = 0;
char *remainingString = (char *)utf8String;
for (int charByteSize; (charByteSize = mpw_charByteSize( *remainingString )); remainingString += charByteSize)
for (int charByteSize; (charByteSize = mpw_charByteSize( (unsigned char)*remainingString )); remainingString += charByteSize)
++charlen;
return charlen;
return charlen;
}

View File

@ -463,26 +463,26 @@
- (void)useSite {
MPSiteModel *selectedSite = [self selectedSite];
if (selectedSite) {
// Performing action while content is available. Copy it.
[self copyContent:selectedSite.content];
if (!selectedSite)
return;
[self fadeOut];
if (selectedSite.transient) {
[self createNewSite:selectedSite.name];
return;
}
NSUserNotification *notification = [NSUserNotification new];
notification.title = @"Password Copied";
if (selectedSite.loginName.length)
notification.subtitle = strf( @"%@ at %@", selectedSite.loginName, selectedSite.name );
else
notification.subtitle = selectedSite.name;
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
}
else {
NSString *siteName = [self.siteField stringValue];
if ([siteName length])
// Performing action without content but a site name is written.
[self createNewSite:siteName];
}
// Performing action while content is available. Copy it.
[self copyContent:selectedSite.content];
[self fadeOut];
NSUserNotification *notification = [NSUserNotification new];
notification.title = @"Password Copied";
if (selectedSite.loginName.length)
notification.subtitle = strf( @"%@ at %@", selectedSite.loginName, selectedSite.name );
else
notification.subtitle = selectedSite.name;
[[NSUserNotificationCenter defaultUserNotificationCenter] deliverNotification:notification];
}
- (void)updateUser {
@ -549,9 +549,15 @@
return;
}
BOOL exact = NO;
NSMutableArray *newSites = [NSMutableArray arrayWithCapacity:[siteResults count]];
for (MPSiteEntity *site in siteResults)
for (MPSiteEntity *site in siteResults) {
[newSites addObject:[[MPSiteModel alloc] initWithEntity:site fuzzyGroups:fuzzyGroups]];
exact |= [site.name isEqualToString:queryString];
}
if (!exact && [queryString length])
[newSites addObject:[[MPSiteModel alloc] initWithName:queryString]];
dbg( @"newSites: %@", newSites );
self.sites = newSites;
}];
}

View File

@ -35,10 +35,12 @@
@property (nonatomic) NSUInteger counter;
@property (nonatomic) NSDate *lastUsed;
@property (nonatomic) id<MPAlgorithm> algorithm;
@property (nonatomic) BOOL generated;
@property (nonatomic) BOOL stored;
@property (nonatomic, readonly) BOOL generated;
@property (nonatomic, readonly) BOOL stored;
@property (nonatomic, readonly) BOOL transient;
- (instancetype)initWithEntity:(MPSiteEntity *)entity fuzzyGroups:(NSArray *)fuzzyGroups;
- (instancetype)initWithName:(NSString *)siteName;
- (MPSiteEntity *)entityInContext:(NSManagedObjectContext *)moc;
- (void)updateContent;

View File

@ -28,7 +28,7 @@
BOOL _initialized;
}
- (id)initWithEntity:(MPSiteEntity *)entity fuzzyGroups:(NSArray *)fuzzyGroups {
- (instancetype)initWithEntity:(MPSiteEntity *)entity fuzzyGroups:(NSArray *)fuzzyGroups {
if (!(self = [super init]))
return nil;
@ -39,6 +39,17 @@
return self;
}
- (instancetype)initWithName:(NSString *)siteName {
if (!(self = [super init]))
return nil;
[self setTransientSiteName:siteName];
_initialized = YES;
return self;
}
- (void)setEntity:(MPSiteEntity *)entity fuzzyGroups:(NSArray *)fuzzyGroups {
if ([_entityOID isEqual:entity.objectID])
@ -73,6 +84,28 @@
[self updateContent:entity];
}
- (void)setTransientSiteName:(NSString *)siteName {
_entityOID = nil;
NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new];
paragraphStyle.alignment = NSCenterTextAlignment;
self.displayedName = stra( siteName, @{
NSBackgroundColorAttributeName : [NSColor alternateSelectedControlColor],
NSParagraphStyleAttributeName : paragraphStyle,
} );
self.name = siteName;
self.algorithm = MPAlgorithmDefault;
self.lastUsed = nil;
self.type = [MPAppDelegate_Shared get].activeUserForMainThread.defaultType;
self.typeName = [self.algorithm nameOfType:self.type];
self.uses = @0;
self.counter = 1;
// Find all password types and the index of the current type amongst them.
[self updateContent];
}
- (MPSiteEntity *)entityInContext:(NSManagedObjectContext *)moc {
if (!_entityOID)
@ -96,15 +129,18 @@
// This wasn't a change to the entity.
return;
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPSiteEntity *entity = [self entityInContext:context];
if ([entity isKindOfClass:[MPGeneratedSiteEntity class]]) {
((MPGeneratedSiteEntity *)entity).counter = counter;
[context saveToStore];
if (_entityOID)
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
MPSiteEntity *entity = [self entityInContext:context];
if ([entity isKindOfClass:[MPGeneratedSiteEntity class]]) {
((MPGeneratedSiteEntity *)entity).counter = counter;
[context saveToStore];
[self updateContent:entity];
}
}];
[self updateContent:entity];
}
}];
else
[self updateContent];
}
- (BOOL)generated {
@ -117,36 +153,60 @@
return self.type & MPSiteTypeClassStored;
}
- (BOOL)transient {
return _entityOID == nil;
}
- (void)updateContent {
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
[self updateContent:[MPSiteEntity existingObjectWithID:_entityOID inContext:context]];
}];
if (_entityOID)
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *context) {
[self updateContent:[MPSiteEntity existingObjectWithID:_entityOID inContext:context]];
}];
else
PearlNotMainQueue( ^{
NSString *password = [self.algorithm generatePasswordForSiteNamed:self.name ofType:self.type withCounter:self.counter
usingKey:[MPAppDelegate_Shared get].key];
NSString *loginName = [self.algorithm generateLoginForSiteNamed:self.name usingKey:[MPAppDelegate_Shared get].key];
[self updatePasswordWithResult:password];
[self updateLoginNameWithResult:loginName];
} );
}
- (void)updateContent:(MPSiteEntity *)entity {
[entity resolvePasswordUsingKey:[MPAppDelegate_Shared get].key result:^(NSString *result) {
[self updatePasswordWithResult:result];
}];
[entity resolveLoginUsingKey:[MPAppDelegate_Shared get].key result:^(NSString *result) {
[self updateLoginNameWithResult:result];
}];
}
- (void)updatePasswordWithResult:(NSString *)result {
static NSRegularExpression *re_anyChar;
static dispatch_once_t once = 0;
dispatch_once( &once, ^{
re_anyChar = [NSRegularExpression regularExpressionWithPattern:@"." options:0 error:nil];
} );
[entity resolvePasswordUsingKey:[MPAppDelegate_Shared get].key result:^(NSString *result) {
NSString *displayResult = result;
if ([[MPConfig get].hidePasswords boolValue] && !([NSEvent modifierFlags] & NSAlternateKeyMask))
displayResult = [displayResult stringByReplacingMatchesOfExpression:re_anyChar withTemplate:@"●"];
NSString *displayResult = result;
if ([[MPConfig get].hidePasswords boolValue] && !([NSEvent modifierFlags] & NSAlternateKeyMask))
displayResult = [displayResult stringByReplacingMatchesOfExpression:re_anyChar withTemplate:@"●"];
PearlMainQueue( ^{
self.content = result;
self.displayedContent = displayResult;
} );
}];
[entity resolveLoginUsingKey:[MPAppDelegate_Shared get].key result:^(NSString *result) {
PearlMainQueue( ^{
self.loginName = result;
} );
}];
PearlMainQueue( ^{
self.content = result;
self.displayedContent = displayResult;
} );
}
- (void)updateLoginNameWithResult:(NSString *)loginName {
PearlMainQueue( ^{
self.loginName = loginName;
} );
}
@end