2
0

Improve lock/unlock assurance flow.

[FIXED]     Bug that caused the window to sometimes re-open when closed.
This commit is contained in:
Maarten Billemont 2013-06-09 19:03:54 -04:00
parent 797060f609
commit 08d3d9ad30
6 changed files with 80 additions and 92 deletions

View File

@ -225,7 +225,7 @@
<object class="NSButtonCell" key="NSCell" id="922307452">
<int key="NSCellFlags">67108864</int>
<int key="NSCellFlags2">134217728</int>
<string key="NSContents">Enable iCloud</string>
<string key="NSContents">Use iCloud</string>
<reference key="NSSupport" ref="1068244176"/>
<string key="NSCellIdentifier">_NS:9</string>
<reference key="NSControlView" ref="499448697"/>

View File

@ -204,7 +204,6 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
- (IBAction)terminate:(id)sender {
NSLog( @"Closing: Terminating" );
[self.passwordWindow close];
self.passwordWindow = nil;
@ -215,7 +214,6 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"http://itunes.apple.com/app/id510296984"]];
NSLog( @"Closing: App Store" );
[self.initialWindow close];
self.initialWindow = nil;
}
@ -271,7 +269,6 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
if (![self.passwordWindow.window isVisible])
self.passwordWindow = nil;
else {
NSLog( @"Closing: dialogStyleHUD && passwordWindow.isVisible" );
[self.passwordWindow close];
self.passwordWindow = nil;
[self showPasswordWindow:nil];
@ -305,8 +302,6 @@ static OSStatus MPHotKeyHander(EventHandlerCallRef nextHandler, EventRef theEven
BOOL reopenPasswordWindow = [self.passwordWindow.window isVisible];
if (![[self activeUserForThread].objectID isEqual:activeUser.objectID]) {
NSLog( @"Closing: activeUser changed: %@ -> %@, reopening: %d", [self activeUserForThread].objectID, activeUser.objectID,
reopenPasswordWindow );
[self.passwordWindow close];
self.passwordWindow = nil;
[super setActiveUser:activeUser];

View File

@ -17,7 +17,6 @@
@property(nonatomic, weak) IBOutlet NSProgressIndicator *progressView;
@property(nonatomic, weak) IBOutlet NSTextField *userLabel;
- (void)unlock;
- (IBAction)reload:(id)sender;
@end

View File

@ -22,6 +22,7 @@
@property(nonatomic, strong) NSOperationQueue *backgroundQueue;
@property(nonatomic, strong) NSAlert *loadingDataAlert;
@property(nonatomic) BOOL closing;
@end
@implementation MPPasswordWindowController {
@ -30,7 +31,6 @@
- (void)windowDidLoad {
NSLog(@"DidLoad:\n%@", [NSThread callStackSymbols]);
if ([[MPMacConfig get].dialogStyleHUD boolValue])
self.window.styleMask = NSHUDWindowMask | NSTitledWindowMask | NSUtilityWindowMask | NSClosableWindowMask;
else
@ -52,73 +52,63 @@
// @"their passwords to change. You'll need to update your profile for that site with the new password."];
// [moc saveToStore];
// }];
[self handleUnloadedOrLocked];
} forKeyPath:@"key" options:NSKeyValueObservingOptionInitial context:nil];
[self ensureLoadedAndUnlockedOrCloseIfLoggedOut:YES];
} forKeyPath:@"key" options:NSKeyValueObservingOptionInitial context:nil];
[[NSNotificationCenter defaultCenter]
addObserverForName:NSWindowDidBecomeKeyNotification object:self.window queue:nil usingBlock:^(NSNotification *note) {
NSLog(@"DidBecomeKey:\n%@", [NSThread callStackSymbols]);
[self checkLoadedAndUnlocked];
[self ensureLoadedAndUnlockedOrCloseIfLoggedOut:NO];
[self.siteField selectText:nil];
}];
[[NSNotificationCenter defaultCenter]
addObserverForName:NSWindowWillCloseNotification object:self.window queue:nil usingBlock:^(NSNotification *note) {
NSLog(@"WillClose:\n%@", [NSThread callStackSymbols]);
NSWindow *sheet = [self.window attachedSheet];
if (sheet)
[NSApp endSheet:sheet];
[NSApp hide:nil];
dispatch_async( dispatch_get_main_queue(), ^{
NSWindow *sheet = [self.window attachedSheet];
if (sheet)
[NSApp endSheet:sheet];
[NSApp hide:nil];
self.closing = NO;
} );
}];
[[NSNotificationCenter defaultCenter]
addObserverForName:MPSignedOutNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
_activeElementOID = nil;
[self.siteField setStringValue:@""];
[self trySiteWithAction:NO];
[self handleUnloadedOrLocked];
[self ensureLoadedAndUnlockedOrCloseIfLoggedOut:YES];
}];
[[NSNotificationCenter defaultCenter]
addObserverForName:USMStoreDidChangeNotification object:nil queue:nil usingBlock:^(NSNotification *note) {
[self checkLoadedAndUnlocked];
[self ensureLoadedAndUnlockedOrCloseIfLoggedOut:NO];
}];
[super windowDidLoad];
}
- (BOOL)shouldCloseDocument {
NSLog(@"shouldCloseDocument:\n%@", [NSThread callStackSymbols]);
return [super shouldCloseDocument];
}
- (void)close {
NSLog(@"close:\n%@", [NSThread callStackSymbols]);
self.closing = YES;
[super close];
}
- (void)handleUnloadedOrLocked {
- (BOOL)ensureLoadedAndUnlockedOrCloseIfLoggedOut:(BOOL)closeIfLoggedOut {
if (!self.inProgress && ![MPMacAppDelegate get].key) {
MPUserEntity *activeUser = [MPMacAppDelegate get].activeUserForThread;
if (activeUser && !activeUser.saveKey)
[self unlock];
else {
NSLog(@"Closing: !inProgress && !key && (!activeUser || activeUser.saveKey)");
[self.window close];
}
}
if (![self ensureStoreLoaded])
return NO;
if (self.closing || self.inProgress || !self.window.isKeyWindow)
return NO;
return [self ensureUnlocked:closeIfLoggedOut];
}
- (void)checkLoadedAndUnlocked {
if ([self waitUntilStoreLoaded] && !self.inProgress)
[self unlock];
}
- (BOOL)waitUntilStoreLoaded {
- (BOOL)ensureStoreLoaded {
if ([MPMacAppDelegate managedObjectContextForThreadIfReady]) {
[NSApp endSheet:self.loadingDataAlert.window];
// Store loaded.
if (self.loadingDataAlert.window)
[NSApp endSheet:self.loadingDataAlert.window];
return YES;
}
@ -130,43 +120,57 @@
return NO;
}
- (void)unlock {
- (BOOL)ensureUnlocked:(BOOL)closeIfLoggedOut {
[MPMacAppDelegate managedObjectContextPerformBlock:^(NSManagedObjectContext *moc) {
__block BOOL unlocked = NO;
[MPMacAppDelegate managedObjectContextPerformBlockAndWait:^(NSManagedObjectContext *moc) {
MPUserEntity *activeUser = [[MPMacAppDelegate get] activeUserInContext:moc];
NSString *userName = activeUser.name;
if (!activeUser)
// No user to sign in with.
if (!activeUser) {
// No user to sign in with.
if (closeIfLoggedOut)
[self close];
return;
if ([MPMacAppDelegate get].key)
// Already logged in.
}
if ([MPMacAppDelegate get].key) {
// Already logged in.
unlocked = YES;
return;
if ([[MPMacAppDelegate get] signInAsUser:activeUser saveInContext:moc usingMasterPassword:nil])
// Load the key from the keychain.
}
if (activeUser.saveKey && closeIfLoggedOut) {
// App was locked, don't instantly unlock again.
[self close];
return;
}
if ([[MPMacAppDelegate get] signInAsUser:activeUser saveInContext:moc usingMasterPassword:nil]) {
// Loaded the key from the keychain.
unlocked = YES;
return;
}
if (![MPMacAppDelegate get].key)
// Ask the user to set the key through his master password.
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
if ([MPMacAppDelegate get].key)
return;
// Ask the user to set the key through his master password.
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
if ([MPMacAppDelegate get].key)
return;
self.content = @"";
[self.siteField setStringValue:@""];
[self.tipField setStringValue:@""];
self.content = @"";
[self.siteField setStringValue:@""];
[self.tipField setStringValue:@""];
NSAlert *alert = [NSAlert alertWithMessageText:@"Master Password is locked."
defaultButton:@"Unlock" alternateButton:@"Change" otherButton:@"Cancel"
informativeTextWithFormat:@"The master password is required to unlock the application for:\n\n%@",
userName];
NSSecureTextField *passwordField = [[NSSecureTextField alloc] initWithFrame:NSMakeRect( 0, 0, 200, 22 )];
[alert setAccessoryView:passwordField];
[alert layout];
[passwordField becomeFirstResponder];
[alert beginSheetModalForWindow:self.window modalDelegate:self
didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:MPAlertUnlockMP];
}];
NSAlert *alert = [NSAlert alertWithMessageText:@"Master Password is locked."
defaultButton:@"Unlock" alternateButton:@"Change" otherButton:@"Cancel"
informativeTextWithFormat:@"The master password is required to unlock the application for:\n\n%@",
userName];
NSSecureTextField *passwordField = [[NSSecureTextField alloc] initWithFrame:NSMakeRect( 0, 0, 200, 22 )];
[alert setAccessoryView:passwordField];
[alert layout];
[passwordField becomeFirstResponder];
[alert beginSheetModalForWindow:self.window modalDelegate:self
didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:MPAlertUnlockMP];
}];
}];
return unlocked;
}
- (IBAction)reload:(id)sender {
@ -177,8 +181,7 @@
- (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo {
if (contextInfo == MPAlertIncorrectMP) {
NSLog(@"Closing: Incorrect MP, button: %ld", returnCode);
[self.window close];
[self close];
return;
}
if (contextInfo == MPAlertUnlockMP) {
@ -209,9 +212,8 @@
case NSAlertOtherReturn: {
// "Cancel" button.
NSLog(@"Closing: Unlock MP, button: %ld", (long)returnCode);
[self.window close];
return;
[self close];
break;
}
case NSAlertDefaultReturn: {
@ -228,7 +230,7 @@
usingMasterPassword:password];
self.inProgress = NO;
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
dispatch_async( dispatch_get_current_queue(), ^{
[self.progressView stopAnimation:nil];
if (success)
@ -239,7 +241,7 @@
}]] beginSheetModalForWindow:self.window modalDelegate:self
didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) contextInfo:MPAlertIncorrectMP];
}
}];
} );
}];
break;
}
@ -307,8 +309,7 @@
- (BOOL)control:(NSControl *)control textView:(NSTextView *)fieldEditor doCommandBySelector:(SEL)commandSelector {
if (commandSelector == @selector(cancel:)) { // Escape without completion.
NSLog(@"Closing: ESC without completion");
[self.window close];
[self close];
return YES;
}
if ((self.siteFieldPreventCompletion = [NSStringFromSelector( commandSelector ) hasPrefix:@"delete"])) { // Backspace any time.
@ -399,7 +400,6 @@
if (!content)
content = @"";
dbg(@"name: %@, action: %d", siteName, doAction);
if (doAction) {
if ([content length]) {
// Performing action while content is available. Copy it.

View File

@ -15,7 +15,7 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DA5BFA43147E415C00F98B1E"
BuildableName = "MasterPassword.app"
BuildableName = "Master Password.app"
BlueprintName = "MasterPassword"
ReferencedContainer = "container:MasterPassword-Mac.xcodeproj">
</BuildableReference>
@ -43,7 +43,7 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DA5BFA43147E415C00F98B1E"
BuildableName = "MasterPassword.app"
BuildableName = "Master Password.app"
BlueprintName = "MasterPassword"
ReferencedContainer = "container:MasterPassword-Mac.xcodeproj">
</BuildableReference>

View File

@ -15,7 +15,7 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DA5BFA43147E415C00F98B1E"
BuildableName = "MasterPassword.app"
BuildableName = "Master Password.app"
BlueprintName = "MasterPassword"
ReferencedContainer = "container:MasterPassword-Mac.xcodeproj">
</BuildableReference>
@ -43,17 +43,11 @@
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DA5BFA43147E415C00F98B1E"
BuildableName = "MasterPassword.app"
BuildableName = "Master Password.app"
BlueprintName = "MasterPassword"
ReferencedContainer = "container:MasterPassword-Mac.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<CommandLineArguments>
<CommandLineArgument
argument = "-com.apple.coredata.ubiquity.logLevel 3"
isEnabled = "NO">
</CommandLineArgument>
</CommandLineArguments>
<EnvironmentVariables>
<EnvironmentVariable
key = "CA_DEBUG_TRANSACTIONS"