diff --git a/MacPass.xcodeproj/project.pbxproj b/MacPass.xcodeproj/project.pbxproj index 584cc05e..a84a6489 100644 --- a/MacPass.xcodeproj/project.pbxproj +++ b/MacPass.xcodeproj/project.pbxproj @@ -108,6 +108,7 @@ 4C4B7EEE17A467E1000234C7 /* MPGroupInspectorViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C4B7EEC17A467E1000234C7 /* MPGroupInspectorViewController.m */; }; 4C4B7EF317A467FC000234C7 /* MPEntryInspectorViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C4B7EF117A467FC000234C7 /* MPEntryInspectorViewController.m */; }; 4C4B7EF817A4B335000234C7 /* MPUniqueCharactersFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C4B7EF717A4B335000234C7 /* MPUniqueCharactersFormatter.m */; }; + 4C4DC0A61C3AD17500DE9DCF /* KeePassKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C7B63791C0CB55600D7038C /* KeePassKit.framework */; }; 4C4F72D118DF704400E8D378 /* DDHotKeyTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C4F72CF18DF704400E8D378 /* DDHotKeyTextField.m */; }; 4C4FCE15177CFE6B00BBF7AE /* MPCustomFieldTableCellView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C4FCE14177CFE6B00BBF7AE /* MPCustomFieldTableCellView.m */; }; 4C52A88E1788628B00868229 /* 06_BlockDeviceTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C52A88B1788628B00868229 /* 06_BlockDeviceTemplate.pdf */; }; @@ -178,6 +179,7 @@ 4C89B71019B4B4A300DC0A6A /* MPTreeDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C89B70F19B4B4A300DC0A6A /* MPTreeDelegate.m */; }; 4C89F524182FB4740069C73C /* MPAutotypeCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C89F523182FB4740069C73C /* MPAutotypeCommand.m */; }; 4C8B36AB17A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8B36AA17A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.m */; }; + 4C8DEAA21C314D2C00D24C32 /* MPTestAutotypeDelay.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8DEAA11C314D2C00D24C32 /* MPTestAutotypeDelay.m */; }; 4C94A0721938DDC20040ABAB /* MPDocument+EditingSession.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C94A0711938DDC20040ABAB /* MPDocument+EditingSession.m */; }; 4C978E0D19AE54AB003067DF /* MPFlagsHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C978E0C19AE54AB003067DF /* MPFlagsHelper.m */; }; 4CA08DA017A831B200A6544B /* MPAddEntryContextMenuDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4CA08D9F17A831B200A6544B /* MPAddEntryContextMenuDelegate.m */; }; @@ -536,6 +538,7 @@ 4C89F523182FB4740069C73C /* MPAutotypeCommand.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPAutotypeCommand.m; sourceTree = ""; }; 4C8B36A917A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPOutlineContextMenuDelegate.h; sourceTree = ""; }; 4C8B36AA17A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPOutlineContextMenuDelegate.m; sourceTree = ""; }; + 4C8DEAA11C314D2C00D24C32 /* MPTestAutotypeDelay.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPTestAutotypeDelay.m; sourceTree = ""; }; 4C94A0711938DDC20040ABAB /* MPDocument+EditingSession.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "MPDocument+EditingSession.m"; sourceTree = ""; }; 4C978E0C19AE54AB003067DF /* MPFlagsHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPFlagsHelper.m; sourceTree = ""; }; 4CA08D9E17A831B200A6544B /* MPAddEntryContextMenuDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MPAddEntryContextMenuDelegate.h; sourceTree = ""; }; @@ -741,6 +744,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 4C4DC0A61C3AD17500DE9DCF /* KeePassKit.framework in Frameworks */, 4C473A8718AFD85B0073FD2E /* XCTest.framework in Frameworks */, 4C45FB1D178E09ED0010007D /* Cocoa.framework in Frameworks */, ); @@ -942,6 +946,7 @@ children = ( 4CCFA12C1BF0CC7A0078E0A1 /* Databases */, 4C10207E1B750E2F00BFCD59 /* MPTestAutotype.m */, + 4C8DEAA11C314D2C00D24C32 /* MPTestAutotypeDelay.m */, 4C45FB2C178E0BCB0010007D /* MPDatabaseLoading.m */, 4C45FB2F178E0CE20010007D /* MPTestDocument.m */, 4C6BC65F1A36717E00BDDF3D /* MPDatabaseSearch.m */, @@ -1620,6 +1625,7 @@ buildActionMask = 2147483647; files = ( 4C45FB2D178E0BCB0010007D /* MPDatabaseLoading.m in Sources */, + 4C8DEAA21C314D2C00D24C32 /* MPTestAutotypeDelay.m in Sources */, 4C45FB30178E0CE20010007D /* MPTestDocument.m in Sources */, 4C6BC6601A36717E00BDDF3D /* MPDatabaseSearch.m in Sources */, 4C10207F1B750E2F00BFCD59 /* MPTestAutotype.m in Sources */, @@ -2051,6 +2057,7 @@ FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(DEVELOPER_FRAMEWORKS_DIR)", + "$(PROJECT_DIR)/Carthage/Build/Mac", ); GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "MacPassTests/MacPassTests-Prefix.pch"; @@ -2075,6 +2082,7 @@ FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(DEVELOPER_FRAMEWORKS_DIR)", + "$(PROJECT_DIR)/Carthage/Build/Mac", ); GCC_PRECOMPILE_PREFIX_HEADER = YES; GCC_PREFIX_HEADER = "MacPassTests/MacPassTests-Prefix.pch"; diff --git a/MacPass/MPAutotypeDelay.h b/MacPass/MPAutotypeDelay.h index 3ebc749e..c086b456 100644 --- a/MacPass/MPAutotypeDelay.h +++ b/MacPass/MPAutotypeDelay.h @@ -9,6 +9,8 @@ #import "MPAutotypeCommand.h" @interface MPAutotypeDelay : MPAutotypeCommand + +@property (readonly) NSUInteger delay; /** * Creates an DelayCommand that delays the execution for n milliseconds * diff --git a/MacPass/MPAutotypeDelay.m b/MacPass/MPAutotypeDelay.m index f25575f3..a267a64b 100644 --- a/MacPass/MPAutotypeDelay.m +++ b/MacPass/MPAutotypeDelay.m @@ -8,10 +8,8 @@ #import "MPAutotypeDelay.h" -@interface MPAutotypeDelay () { -@private - NSUInteger _delay; -} +@interface MPAutotypeDelay () +@property (readwrite) NSUInteger delay; @end @implementation MPAutotypeDelay @@ -22,7 +20,7 @@ } - (NSString *)description { - return [[NSString alloc] initWithFormat:@"%@ delay: %ld ms", self.class, _delay]; + return [[NSString alloc] initWithFormat:@"%@ delay: %ld ms", self.class, self.delay]; } - (instancetype)initWithDelay:(NSUInteger)delay { @@ -36,7 +34,7 @@ - (void)execute { /* milliseconds * 10000 = microseconds */ - usleep((useconds_t)(_delay*1000)); + usleep((useconds_t)(self.delay*1000)); } @end diff --git a/MacPass/MPDocument.h b/MacPass/MPDocument.h index 2a73ffe3..2a0b4b28 100644 --- a/MacPass/MPDocument.h +++ b/MacPass/MPDocument.h @@ -21,7 +21,7 @@ // #import -#import "KeePassKit/KeePassKit.h" +#import #import "MPEntrySearchContext.h" #import "MPTargetNodeResolving.h" diff --git a/MacPass/MPPlugin.h b/MacPass/MPPlugin.h index 4afbee61..fc4eddf8 100644 --- a/MacPass/MPPlugin.h +++ b/MacPass/MPPlugin.h @@ -35,5 +35,21 @@ FOUNDATION_EXPORT NSString *const kMPPluginFileExtension; @end +@class KPKTree; + +@protocol MPTreeImporting + +@required +- (KPKTree *)importTreeAtURL:(NSURL *)url error:(NSError **)error; + +@end + +@protocol MPTreeExporting + +@required +- (NSData *)dataForTree:(KPKTree *)tree error:(NSError **)error; + +@end + NS_ASSUME_NONNULL_END \ No newline at end of file diff --git a/MacPass/MPPluginManager.m b/MacPass/MPPluginManager.m index aa5d82c0..d525790f 100644 --- a/MacPass/MPPluginManager.m +++ b/MacPass/MPPluginManager.m @@ -43,10 +43,6 @@ NSString *const MPPluginManagerPluginBundleIdentifiyerKey = @"MPPluginManagerPlu return instance; } -- (void)dealloc { - NSLog(@"%@ dealloc", [self class]); -} - - (instancetype)init { return nil; } @@ -71,16 +67,30 @@ NSString *const MPPluginManagerPluginBundleIdentifiyerKey = @"MPPluginManagerPlu } - (void)_loadPlugins { - NSURL *dir = [NSApp applicationSupportDirectoryURL:YES]; + NSURL *appSupportDir = [NSApp applicationSupportDirectoryURL:YES]; NSError *error; - NSArray *contentURLs = [[NSFileManager defaultManager] contentsOfDirectoryAtURL:dir + NSArray *externalPluginsURLs = [[NSFileManager defaultManager] contentsOfDirectoryAtURL:appSupportDir includingPropertiesForKeys:@[] options:NSDirectoryEnumerationSkipsHiddenFiles error:&error]; - if(!contentURLs) { - NSLog(@"Error while trying to locate Plugins: %@", error.localizedDescription); + + NSArray *internalPluginsURLs = [[NSFileManager defaultManager] contentsOfDirectoryAtURL:[NSBundle mainBundle].builtInPlugInsURL + includingPropertiesForKeys:@[] + options:NSDirectoryEnumerationSkipsHiddenFiles + error:&error]; + + + if(!externalPluginsURLs) { + // No external plugins + NSLog(@"No external plugins found!"); } - for(NSURL *pluginURL in contentURLs) { + if(!internalPluginsURLs) { + // No internal plugins + NSLog(@"No internal plugins found!"); + } + NSArray *pluginURLs = [externalPluginsURLs arrayByAddingObjectsFromArray:internalPluginsURLs]; + + for(NSURL *pluginURL in pluginURLs) { if(![self _validURL:pluginURL]) { continue; @@ -113,12 +123,16 @@ NSString *const MPPluginManagerPluginBundleIdentifiyerKey = @"MPPluginManagerPlu MPPlugin *plugin = [[pluginBundle.principalClass alloc] initWithPluginManager:self]; if(plugin) { NSLog(@"Loaded plugin instance %@", pluginBundle.principalClass); - [[NSNotificationCenter defaultCenter] postNotificationName:MPPluginManagerWillLoadPlugin object:self userInfo:@{ MPPluginManagerPluginBundleIdentifiyerKey : plugin.identifier }]; + [[NSNotificationCenter defaultCenter] postNotificationName:MPPluginManagerWillLoadPlugin + object:self + userInfo:@{ MPPluginManagerPluginBundleIdentifiyerKey : plugin.identifier }]; [self.mutablePlugins addObject:plugin]; - [[NSNotificationCenter defaultCenter] postNotificationName:MPPluginManagerDidLoadPlugin object:self userInfo:@{ MPPluginManagerPluginBundleIdentifiyerKey : plugin.identifier }]; + [[NSNotificationCenter defaultCenter] postNotificationName:MPPluginManagerDidLoadPlugin + object:self + userInfo:@{ MPPluginManagerPluginBundleIdentifiyerKey : plugin.identifier }]; } else { - NSLog(@"Unable to instanciate instance of plugin class %@", pluginBundle.principalClass); + NSLog(@"Unable to create instance of plugin class %@", pluginBundle.principalClass); } } } diff --git a/MacPass/de.lproj/Localizable.strings b/MacPass/de.lproj/Localizable.strings index 10ff2c58..b3789193 100644 Binary files a/MacPass/de.lproj/Localizable.strings and b/MacPass/de.lproj/Localizable.strings differ diff --git a/MacPassTests/MPDatabaseLoading.m b/MacPassTests/MPDatabaseLoading.m index 0e060040..3eba9cf1 100644 --- a/MacPassTests/MPDatabaseLoading.m +++ b/MacPassTests/MPDatabaseLoading.m @@ -7,9 +7,9 @@ // #import +#import #import "MPDocument.h" -#import "KeePassKit/KeePassKit.h" @interface MPDatabaseLoading : XCTestCase diff --git a/MacPassTests/MPDatabaseSearch.m b/MacPassTests/MPDatabaseSearch.m index d61f50ed..10089123 100644 --- a/MacPassTests/MPDatabaseSearch.m +++ b/MacPassTests/MPDatabaseSearch.m @@ -8,8 +8,7 @@ #import #import - -#import "KeePassKit/KeePassKit.h" +#import @interface MPDatabaseSearch : XCTestCase diff --git a/MacPassTests/MPTestAutotype.m b/MacPassTests/MPTestAutotype.m index e1e621aa..39b680c4 100644 --- a/MacPassTests/MPTestAutotype.m +++ b/MacPassTests/MPTestAutotype.m @@ -9,6 +9,7 @@ #import #import #import +#import #import "MPAutotypeCommand.h" #import "MPAutotypeContext.h" @@ -17,7 +18,6 @@ #import "MPKeyMapper.h" -#import "KeePassKit/KeePassKit.h" @interface MPTestAutotype : XCTestCase @property (strong) KPKEntry *entry; diff --git a/MacPassTests/MPTestAutotypeDelay.m b/MacPassTests/MPTestAutotypeDelay.m new file mode 100644 index 00000000..c02c077f --- /dev/null +++ b/MacPassTests/MPTestAutotypeDelay.m @@ -0,0 +1,70 @@ +// +// MPTestAutotypeDelay.m +// MacPass +// +// Created by Michael Starke on 28/12/15. +// Copyright © 2015 HicknHack Software GmbH. All rights reserved. +// + +#import +#import + +#import "MPAutotypeContext.h" +#import "MPAutotypeDelay.h" + +@interface MPTestAutotypeDelay : XCTestCase +@property (strong) KPKEntry *entry; +@end + +@implementation MPTestAutotypeDelay + +- (void)setUp { + [super setUp]; + self.entry = [[KPKEntry alloc] init]; + self.entry.title = @"Title"; + self.entry.url = @"www.myurl.com"; + self.entry.username = @"Username"; + self.entry.password = @"Password"; +} + +- (void)tearDown { + [super tearDown]; +} + +- (void)testValidDelayCommands { + /* Command 1 */ + MPAutotypeContext *context = [[MPAutotypeContext alloc] initWithEntry:self.entry andSequence:@"{DELAY 200}"]; + NSArray *commands = [MPAutotypeCommand commandsForContext:context]; + + XCTAssertTrue(commands.count == 1); + /* {DELAY 200} */ + XCTAssertTrue([commands.firstObject isKindOfClass:[MPAutotypeDelay class]], @"Command is Delay command"); + MPAutotypeDelay *delay = commands.firstObject; + XCTAssertEqual(delay.delay, 200, @"Delay is 200 ms"); +} + +- (void)testDelayExecution { + MPAutotypeDelay *delay = [[MPAutotypeDelay alloc] initWithDelay:200]; + XCTestExpectation *expectation = [self expectationWithDescription:delay.description]; + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + [delay execute]; + [expectation fulfill]; + }); + + [self waitForExpectationsWithTimeout:(delay.delay/1000.0) handler:^(NSError *error) { + if (error != nil) { + NSLog(@"Error: %@", error.localizedDescription); + } + }]; +} + + +- (void)testDelayLimit { + XCTFail(@"Missing Test"); +} + +- (void)testMalformedDelay { + XCTFail(@"Missing Test"); +} + +@end diff --git a/MacPassTests/MPTestDocument.m b/MacPassTests/MPTestDocument.m index 3dbaee39..eaf9378b 100644 --- a/MacPassTests/MPTestDocument.m +++ b/MacPassTests/MPTestDocument.m @@ -7,9 +7,10 @@ // #import +#import #import "MPDocument.h" -#import "KeePassKit/KeePassKit.h" + @interface MPTestDocument : XCTestCase @end