Autotype fix dialog now only shows candiates.

This commit is contained in:
michael starke
2014-08-11 15:46:32 +02:00
parent 113c620ead
commit 2371793da4
13 changed files with 178 additions and 105 deletions

View File

@@ -1,13 +1,14 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="5053" systemVersion="13C64" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="5056" systemVersion="13E28" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES">
<dependencies>
<deployment defaultVersion="1080" identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="5053"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="5056"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="MPGroupInspectorViewController">
<connections>
<outlet property="autotypePopupButton" destination="240" id="285"/>
<outlet property="autotypeSequenceTextField" destination="Fnw-qz-IZU" id="a7M-zz-0ye"/>
<outlet property="contentView" destination="38" id="Dv7-1B-VeH"/>
<outlet property="expireDateSelectButton" destination="4" id="Bzg-8k-0OS"/>
<outlet property="expiresCheckButton" destination="5" id="283"/>

View File

@@ -8,16 +8,10 @@
#import <Foundation/Foundation.h>
@class MPDocument;
@interface MPAutotypeHelper : NSObject
/**
* Tests the given item for a possible wrong autotype format
* MacPass 0.4 and 0.4.1 did store wrong Autotype sequences and thus mangled database files
*
* @param item Item to test for malformation. Allowed Items are KPKNode, KPKEntry, KPKGroup and KPKAutotype
*
* @return YES if the given item is considered a possible candiate. NO in all other cases
*/
+ (BOOL)isCandidateForMalformedAutotype:(id)item;
@end

View File

@@ -8,6 +8,9 @@
#import "MPAutotypeHelper.h"
#import "MPDocument.h"
#import "KPKTree.h"
#import "KPKGroup.h"
#import "KPKEntry.h"
@@ -16,20 +19,6 @@
@implementation MPAutotypeHelper
+ (BOOL)isCandidateForMalformedAutotype:(id)item {
NSString *keystrokeSequence;
if([item isKindOfClass:[KPKEntry class]] && ![((KPKEntry *)item).autotype hasDefaultKeystrokeSequence]) {
keystrokeSequence = ((KPKEntry *)item).autotype.defaultKeystrokeSequence;
}
else if( [item isKindOfClass:[KPKGroup class]] && ![item hasDefaultAutotypeSequence]) {
keystrokeSequence = ((KPKGroup *)item).defaultAutoTypeSequence;
}
else if( [item isKindOfClass:[KPKWindowAssociation class]] && ![item hasDefaultKeystrokeSequence]){
keystrokeSequence = ((KPKWindowAssociation *)item).keystrokeSequence;
}
/* if nothing is true, keystrokeSequence is nil an hence return is NO */
return (NSOrderedSame == [@"{TAB}{USERNAME}{TAB}{PASSWORD}{ENTER}" compare:keystrokeSequence options:NSCaseInsensitiveSearch]);
}
@end

View File

@@ -24,6 +24,31 @@
@interface MPDocument (Autotype)
/**
* Tests the given item for a possible wrong autotype format
* MacPass 0.4 and 0.4.1 did store wrong Autotype sequences and thus mangled database files
*
* @param item Item to test for malformation. Allowed Items are KPKNode, KPKEntry, KPKGroup and KPKAutotype
*
* @return YES if the given item is considered a possible candiate. NO in all other cases
*/
+ (BOOL)isCandidateForMalformedAutotype:(id)item;
/**
* Returns an NSArray containing all Autotype Contexts that match the given window title
*
* @param windowTitle Window title to search matches for
*
* @return NSArray of MPAutotypeContexts for the given window title
*/
- (NSArray *)autotypContextsForWindowTitle:(NSString *)windowTitle;
/**
* Checks if the document has malformed autotype items
*
* @return YES if any malformed items are found
*/
- (BOOL)hasMalformedAutotypeItems;
- (NSArray *)malformedAutotypeItems;
@end

View File

@@ -22,6 +22,7 @@
#import "MPDocument+Autotype.h"
#import "MPAutotypeContext.h"
#import "MPAutotypeHelper.h"
#import "KPKGroup.h"
#import "KPKEntry.h"
@@ -30,6 +31,22 @@
@implementation MPDocument (Autotype)
+ (BOOL)isCandidateForMalformedAutotype:(id)item {
NSString *keystrokeSequence;
if([item isKindOfClass:[KPKEntry class]] && ![((KPKEntry *)item).autotype hasDefaultKeystrokeSequence]) {
keystrokeSequence = ((KPKEntry *)item).autotype.defaultKeystrokeSequence;
}
else if( [item isKindOfClass:[KPKGroup class]] && ![item hasDefaultAutotypeSequence]) {
keystrokeSequence = ((KPKGroup *)item).defaultAutoTypeSequence;
}
else if( [item isKindOfClass:[KPKWindowAssociation class]] && ![item hasDefaultKeystrokeSequence]){
keystrokeSequence = ((KPKWindowAssociation *)item).keystrokeSequence;
}
/* if nothing is true, keystrokeSequence is nil an hence return is NO */
return (NSOrderedSame == [@"{TAB}{USERNAME}{TAB}{PASSWORD}{ENTER}" compare:keystrokeSequence options:NSCaseInsensitiveSearch]);
}
- (NSArray *)autotypContextsForWindowTitle:(NSString *)windowTitle {
if(!windowTitle) {
return nil;
@@ -59,4 +76,29 @@
return contexts;
}
- (BOOL)hasMalformedAutotypeItems {
return [[self malformedAutotypeItems] count] > 0;
}
- (NSArray *)malformedAutotypeItems {
NSMutableArray *items = [[NSMutableArray alloc] initWithCapacity:1000];
[self _flattenGroup:self.root toArray:items];
NSPredicate *malformedPrediacte = [NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
return [MPDocument isCandidateForMalformedAutotype:evaluatedObject];
}];
NSArray *malformedItems = [items filteredArrayUsingPredicate:malformedPrediacte];
return malformedItems;
}
- (void)_flattenGroup:(KPKGroup *)group toArray:(NSMutableArray *)array {
[array addObject:group];
for(KPKEntry *entry in group.entries) {
[array addObject:entry];
[array addObjectsFromArray:entry.autotype.associations];
}
for(KPKGroup *childGroup in group.groups) {
[self _flattenGroup:childGroup toArray:array];
}
}
@end

View File

@@ -65,6 +65,7 @@ typedef NS_OPTIONS(NSUInteger, MPEntrySearchFlags) {
@interface MPDocument : NSDocument
@property (nonatomic, readonly, assign) BOOL encrypted;
@property (nonatomic, readonly, assign) NSUInteger unlockCount; // Amount of times the Document was unlocked;
@property (strong, readonly, nonatomic) KPKTree *tree;
@property (nonatomic, weak, readonly) KPKGroup *root;

View File

@@ -64,6 +64,8 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey
NSData *_encryptedData;
}
@property (nonatomic, assign) NSUInteger unlockCount;
@property (strong, nonatomic) MPSavePanelAccessoryViewController *savePanelViewController;
@property (strong, nonatomic) KPKTree *tree;
@@ -120,6 +122,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey
_readOnly = NO;
_activeFlags = MPEntrySearchTitles;
_hasSearch = NO;
_unlockCount = 0;
self.tree = [KPKTree templateTree];
self.tree.metaData.rounds = [[NSUserDefaults standardUserDefaults] integerForKey:kMPSettingsKeyDefaultPasswordRounds];
}
@@ -285,6 +288,7 @@ NSString *const MPDocumentGroupKey = @"MPDocumentGroupKey
self.compositeKey = nil; // clear the key?
}
if(isUnlocked) {
self.unlockCount += 1;
[[NSNotificationCenter defaultCenter] postNotificationName:MPDocumentDidUnlockDatabaseNotification object:self];
}
return isUnlocked;

View File

@@ -9,9 +9,12 @@
#import "MPEntryViewController.h"
#import "MPAppDelegate.h"
#import "MPOutlineViewController.h"
#import "MPDocument.h"
#import "MPDocument+Search.h"
#import "MPDocument+Autotype.h"
#import "MPDocumentWindowController.h"
#import "MPPasteBoardController.h"
#import "MPOverlayWindowController.h"
#import "MPContextBarViewController.h"
@@ -66,7 +69,7 @@ NSString *const _MPTAbleSecurCellView = @"PasswordCell";
@interface MPEntryViewController () {
MPEntryContextMenuDelegate *_menuDelegate;
BOOL _isDisplayingContextBar;
BOOL _showFooterInfo;
BOOL _didUnlock;
}
@property (strong) NSArrayController *entryArrayController;
@@ -191,9 +194,6 @@ NSString *const _MPTAbleSecurCellView = @"PasswordCell";
[self _setupHeaderMenu];
[parentColumn setHidden:YES];
[self.footerInfoText setHidden:!_showFooterInfo];
[self.footerInfoText setStringValue:NSLocalizedString(@"DOCUMENT_AUTOTYPE_CORRUPTION_WARNING", "")];
}
- (NSResponder *)reconmendedFirstResponder {
@@ -225,24 +225,11 @@ NSString *const _MPTAbleSecurCellView = @"PasswordCell";
selector:@selector(_didUpdateSearchResults:)
name:MPDocumentDidChangeSearchResults
object:document];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(_didUnlockDatabase:)
name:MPDocumentDidUnlockDatabaseNotification
object:document];
[self.contextBarViewController registerNotificationsForDocument:document];
/* Setup warning message at the bottom*/
NSArray *array = [[NSUserDefaults standardUserDefaults] arrayForKey:kMPSettingsKeyDocumentsAutotypeFixNoteWasShown];
NSString *path = [[document fileURL] path];
if(!path) {
return; // No path, nothing to do
}
if(![array containsObject:path]) {
array = array ? [array arrayByAddingObject:path] : @[path];
[[NSUserDefaults standardUserDefaults] setObject:array forKey:kMPSettingsKeyDocumentsAutotypeFixNoteWasShown];
[[NSUserDefaults standardUserDefaults] synchronize];
_showFooterInfo = YES;
}
else {
_showFooterInfo = NO;
}
}
#pragma mark NSTableViewDelgate
@@ -405,6 +392,15 @@ NSString *const _MPTAbleSecurCellView = @"PasswordCell";
[self _showContextBar];
}
- (void)_didUnlockDatabase:(NSNotification *)notificiation {
MPDocument *document = [[self windowController] document];
/* If the document was locked and unlocked we do not need to recheck */
if(document.unlockCount != 1) {
[self.footerInfoText setHidden:![document hasMalformedAutotypeItems]];
[self.footerInfoText setStringValue:NSLocalizedString(@"DOCUMENT_AUTOTYPE_CORRUPTION_WARNING", "")];
}
}
#pragma mark ContextBar
- (void)_updateContextBar {
MPDocument *document = [[self windowController] document];

View File

@@ -7,14 +7,17 @@
//
#import "MPFixAutotypeWindowController.h"
#import "MPDocument.h"
#import "MPDocument+Autotype.h"
#import "MPIconHelper.h"
#import "KPKNode.h"
#import "KPKEntry.h"
#import "KPKGroup.h"
#import "KPKAutotype.h"
#import "KPKWindowAssociation.h"
#import "MPIconHelper.h"
NSString *const kMPAutotypeCell = @"AutotypeCell";
NSString *const kMPTitleCell = @"TitleCell";
@@ -31,7 +34,7 @@ NSString *const kMPIconCell = @"IconCell";
@end
@interface MPFixAutotypeWindowController () {
NSMutableArray *_elements;
NSArray *_itemsCache;
BOOL _didRegisterForUndoRedo;
}
@end
@@ -66,7 +69,7 @@ NSString *const kMPIconCell = @"IconCell";
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_didChangeDocument:) name:NSUndoManagerDidUndoChangeNotification object:manager];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_didChangeDocument:) name:NSUndoManagerDidCloseUndoGroupNotification object:manager];
}
_elements = nil;
_itemsCache = nil;
[self.tableView reloadData];
}
@@ -201,11 +204,10 @@ NSString *const kMPIconCell = @"IconCell";
#pragma mark Data accessors
- (NSArray *)entriesAndGroups {
if(nil == _elements) {
_elements = [[NSMutableArray alloc] init];
[self flattenGroup:self.workingDocument.root toArray:_elements];
if(nil == _itemsCache) {
_itemsCache = [self.workingDocument malformedAutotypeItems];
}
return _elements;
return _itemsCache;
}
@@ -222,6 +224,7 @@ NSString *const kMPIconCell = @"IconCell";
#pragma mark NSUndoManagerNotifications
- (void)_didChangeDocument:(NSNotification *)notification {
_itemsCache = nil;
[self.tableView reloadData];
}

View File

@@ -20,6 +20,7 @@
@property (weak) IBOutlet NSPopUpButton *searchPopupButton;
@property (weak) IBOutlet NSPopUpButton *autotypePopupButton;
@property (weak) IBOutlet HNHRoundedTextField *autotypeSequenceTextField;
- (void)setupBindings:(MPDocument *)document;

View File

@@ -66,7 +66,7 @@
}
- (void)setupBindings:(MPDocument *)document {
[self bind:@"group" toObject:document withKeyPath:@"selectedGroup" options:nil];
[self bind:NSStringFromSelector(@selector(group)) toObject:document withKeyPath:NSStringFromSelector(@selector(selectedGroup)) options:nil];
}
- (void)setGroup:(KPKGroup *)group {
@@ -80,16 +80,11 @@
if(self.group) {
[self.titleTextField bind:NSValueBinding toObject:self.group withKeyPath:NSStringFromSelector(@selector(name)) options:nil];
[self.expiresCheckButton bind:NSValueBinding toObject:self.group.timeInfo withKeyPath:NSStringFromSelector(@selector(expires)) options:nil];
[self.expiresCheckButton bind:NSTitleBinding
toObject:self.group.timeInfo
withKeyPath:NSStringFromSelector(@selector(expiryTime))
options:@{ NSValueTransformerNameBindingOption:MPExpiryDateValueTransformer }];
[self.expireDateSelectButton bind:NSHiddenBinding
toObject:self.group.timeInfo
withKeyPath:NSStringFromSelector(@selector(expires))
options:@{ NSValueTransformerNameBindingOption : NSNegateBooleanTransformerName }];
[self.autotypePopupButton bind:NSSelectedTagBinding toObject:self.group withKeyPath:@"isAutoTypeEnabled" options:nil];
[self.searchPopupButton bind:NSSelectedTagBinding toObject:self.group withKeyPath:@"isSearchEnabled" options:nil];
[self.expiresCheckButton bind:NSTitleBinding toObject:self.group.timeInfo withKeyPath:NSStringFromSelector(@selector(expiryTime)) options:@{ NSValueTransformerNameBindingOption:MPExpiryDateValueTransformer }];
[self.expireDateSelectButton bind:NSHiddenBinding toObject:self.group.timeInfo withKeyPath:NSStringFromSelector(@selector(expires)) options:@{ NSValueTransformerNameBindingOption : NSNegateBooleanTransformerName }];
[self.autotypePopupButton bind:NSSelectedTagBinding toObject:self.group withKeyPath:NSStringFromSelector(@selector(isAutoTypeEnabled)) options:nil];
[self.autotypeSequenceTextField bind:NSValueBinding toObject:self.group withKeyPath:NSStringFromSelector(@selector(defaultAutoTypeSequence)) options:nil];
[self.searchPopupButton bind:NSSelectedTagBinding toObject:self.group withKeyPath:NSStringFromSelector(@selector(isSearchEnabled)) options:nil];
}
else {
[self.titleTextField unbind:NSValueBinding];
@@ -98,8 +93,9 @@
[self.expiresCheckButton unbind:NSTitleBinding];
[self.expiresCheckButton setTitle:NSLocalizedString(@"EXPIRES", "")];
[self.expireDateSelectButton unbind:NSHiddenBinding];
[self.autotypePopupButton unbind:NSSelectedTagBinding];
[self.searchPopupButton unbind:NSSelectedTagBinding];
[self.autotypePopupButton unbind:NSSelectedTagBinding];
[self.autotypeSequenceTextField unbind:NSValueBinding];
}
}

View File

@@ -42,15 +42,15 @@ APPKIT_EXTERN NSString *const kMPSettingsKeyLegacyHideNotes;
APPKIT_EXTERN NSString *const kMPSettingsKeyLegacyHideURL;
/* Document/Key Location store */
APPKIT_EXTERN NSString *const kMPSettingsKeyLastDatabasePath;
APPKIT_EXTERN NSString *const kMPSettingsKeyRememeberdKeysForDatabases;
APPKIT_EXTERN NSString *const kMPSettingsKeyRememberKeyFilesForDatabases;
APPKIT_EXTERN NSString *const kMPSettingsKeyLastDatabasePath; // Path to the last opened Database. Workaround if users have disabled the feautere in the OS
APPKIT_EXTERN NSString *const kMPSettingsKeyRememeberdKeysForDatabases; // NSDictionary of all db file urls and the corresponding key file url
APPKIT_EXTERN NSString *const kMPSettingsKeyRememberKeyFilesForDatabases; // YES if key files should be rememberd
/* Autotype */
APPKIT_EXTERN NSString *const kMPSettingsKeySendCommandForControlKey; // Should MacPass swap control for command. This is usefull in a cross plattform environment
APPKIT_EXTERN NSString *const kMPSettingsKeyEnableGlobalAutotype; // Is Global Autotype enabled?
APPKIT_EXTERN NSString *const kMPSettingsKeyGlobalAutotypeKeyDataKey; // The stored Data for the useder defined global autotype key
APPKIT_EXTERN NSString *const kMPSettingsKeyDocumentsAutotypeFixNoteWasShown; //
APPKIT_EXTERN NSString *const kMPDepricatedSettingsKeyDocumentsAutotypeFixNoteWasShown; // YES if Autotype fix was shown
/* Search */
APPKIT_EXTERN NSString *const kMPSettingsKeyEntrySearchFilterMode;

View File

@@ -30,13 +30,12 @@ NSString *const kMPSettingsKeyLegacyHideNotes = @"Legacy
NSString *const kMPSettingsKeyLegacyHideURL = @"LegacyHideURL";
NSString *const kMPSettingsKeyLastDatabasePath = @"LastDatabasePath";
NSString *const kMPSettingsKeyRememeberdKeysForDatabases = @"RememeberdKeysForDatabases";
NSString *const kMPSettingsKeyRememberKeyFilesForDatabases = @"RememberKeyFilesForDatabases";
NSString *const kMPSettingsKeyRememeberdKeysForDatabases = @"RememeberdKeysForDatabases";
NSString *const kMPSettingsKeySendCommandForControlKey = @"SendCommandKeyForControlKey";
NSString *const kMPSettingsKeyEnableGlobalAutotype = @"EnableGlobalAutotype";
NSString *const kMPSettingsKeyGlobalAutotypeKeyDataKey = @"GlobalAutotypeKeyDataKey";
NSString *const kMPSettingsKeyDocumentsAutotypeFixNoteWasShown = @"DocumentsAutotypeFixNoteWasShown";
NSString *const kMPSettingsKeyEntrySearchFilterMode = @"EntrySearchFilterMode";
@@ -50,6 +49,11 @@ NSString *const kMPSettingsKeyPasswordCharacterFlags = @"Passwo
NSString *const kMPSettingsKeyPasswordUseCustomString = @"PasswordUseCustomString";
NSString *const kMPSettingsKeyPasswordCustomString = @"PasswordCustomString";
/* Depricated */
NSString *const kMPDepricatedSettingsKeyRememberKeyFilesForDatabases = @"kMPSettingsKeyRememberKeyFilesForDatabases";
NSString *const kMPDepricatedSettingsKeyLastDatabasePath = @"MPLastDatabasePath";
NSString *const kMPDepricatedSettingsKeyDocumentsAutotypeFixNoteWasShown = @"DocumentsAutotypeFixNoteWasShown";
@implementation MPSettingsHelper
+ (void)setupDefaults {
@@ -66,7 +70,10 @@ NSString *const kMPSettingsKeyPasswordCustomString = @"Passwo
}
+ (NSDictionary *)_standardDefaults {
return @{
static NSDictionary *standardDefaults;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
standardDefaults = @{
kMPSettingsKeyShowInspector: @YES, // Show the Inspector by default
kMPSettingsKeyPasteboardClearTimeout: @30, // 30 seconds
kMPSettingsKeyClearPasteboardOnQuit: @YES,
@@ -95,11 +102,25 @@ NSString *const kMPSettingsKeyPasswordCustomString = @"Passwo
kMPSettingsKeyPasswordUseCustomString: @NO,
kMPSettingsKeyPasswordCustomString: @""
};
});
return standardDefaults;
}
+ (NSArray *)_depircatedSettingsKeys {
static NSArray *depircatedSettings;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
depircatedSettings = @[ kMPDepricatedSettingsKeyRememberKeyFilesForDatabases,
kMPDepricatedSettingsKeyLastDatabasePath,
kMPDepricatedSettingsKeyDocumentsAutotypeFixNoteWasShown ];
});
return depircatedSettings;
}
+ (void)_removeObsolteValues {
/* Clear old style values */
for(NSString *key in @[ @"kMPSettingsKeyRememberKeyFilesForDatabases", @"MPLastDatabasePath" ]) {
for(NSString *key in [self _depircatedSettingsKeys]) {
[[NSUserDefaults standardUserDefaults] removeObjectForKey:key];
}
}