Added setup to store a copy of the plugin.json inside Macpass and use that as fallback as well as if the user denies access to remote systems

This commit is contained in:
Michael Starke
2019-06-25 12:59:51 +02:00
parent 8f5914afd2
commit e0d12bea5a
6 changed files with 105 additions and 33 deletions

View File

@@ -203,6 +203,7 @@
4C8B36AB17A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8B36AA17A6ED4B005E1FF1 /* MPOutlineContextMenuDelegate.m */; };
4C8DEAA21C314D2C00D24C32 /* MPTestAutotypeDelay.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8DEAA11C314D2C00D24C32 /* MPTestAutotypeDelay.m */; };
4C8E889222C223620002C7C8 /* createdTemplate.pdf in Resources */ = {isa = PBXBuildFile; fileRef = 4C8E889122C223620002C7C8 /* createdTemplate.pdf */; };
4C8E889422C227270002C7C8 /* plugins.json in Resources */ = {isa = PBXBuildFile; fileRef = 4C8E889322C227270002C7C8 /* plugins.json */; };
4C8F0C6E1FCEE9B900BE157F /* MPPluginConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8F0C6D1FCEE9B900BE157F /* MPPluginConstants.m */; };
4C8F0C711FCEF91400BE157F /* MPPickcharsParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8F0C701FCEF91400BE157F /* MPPickcharsParser.m */; };
4C8F0C731FCF1B7A00BE157F /* MPTestPickcharsParser.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C8F0C721FCF1B7A00BE157F /* MPTestPickcharsParser.m */; };
@@ -720,6 +721,7 @@
4C8C10061FC489D8003DDD5E /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/PluginPreferences.strings; sourceTree = "<group>"; };
4C8DEAA11C314D2C00D24C32 /* MPTestAutotypeDelay.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MPTestAutotypeDelay.m; sourceTree = "<group>"; };
4C8E889122C223620002C7C8 /* createdTemplate.pdf */ = {isa = PBXFileReference; lastKnownFileType = image.pdf; path = createdTemplate.pdf; sourceTree = "<group>"; };
4C8E889322C227270002C7C8 /* plugins.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = plugins.json; path = Resources/plugins.json; sourceTree = "<group>"; };
4C8F0C6C1FCEE98900BE157F /* MPPluginConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MPPluginConstants.h; sourceTree = "<group>"; };
4C8F0C6D1FCEE9B900BE157F /* MPPluginConstants.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MPPluginConstants.m; sourceTree = "<group>"; };
4C8F0C6F1FCEF91400BE157F /* MPPickcharsParser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MPPickcharsParser.h; sourceTree = "<group>"; };
@@ -1485,6 +1487,7 @@
4C77E36D15B84A240093A587 /* Supporting Files */ = {
isa = PBXGroup;
children = (
4C8E889322C227270002C7C8 /* plugins.json */,
FA13910A1F9CD9EB0033D256 /* Localizable.stringsdict */,
4C888C8E16EB6C91003D34A1 /* Localizable.strings */,
4CB9339716D3A0DD00A13B5D /* Credits.rtf */,
@@ -1924,6 +1927,7 @@
6021FE4B18E13F1D00C3BC51 /* GroupInspectorView.xib in Resources */,
4C3826BF1AD04D8E007D7D67 /* 52_EncryptedTemplate.pdf in Resources */,
4C3826BD1AD04D8E007D7D67 /* 50_FolderTarTemplate.pdf in Resources */,
4C8E889422C227270002C7C8 /* plugins.json in Resources */,
6021FE3B18E1341900C3BC51 /* EntryInspectorView.xib in Resources */,
4C3826AD1AD04D8E007D7D67 /* 32_FileSystemViewTemplate.pdf in Resources */,
6021FE6118E15D9100C3BC51 /* WorkflowPreferences.xib in Resources */,

View File

@@ -23,6 +23,7 @@
#import "MPPluginRepository.h"
#import "MPConstants.h"
#import "MPPluginRepositoryItem.h"
#import "MPSettingsHelper.h"
NSString *const MPPluginRepositoryDidUpdateAvailablePluginsNotification = @"com.hicknhack.macpass.MPPluginRepositoryDidInitializeAvailablePluginsNotification";
@@ -56,7 +57,7 @@ NSString *const MPPluginRepositoryDidUpdateAvailablePluginsNotification = @"com.
if(self) {
_isInitialized = NO;
_lastDataFetchTime = NSDate.distantPast.timeIntervalSinceReferenceDate;
[self fetchRepositoryDataCompletionHandler:^(NSArray<MPPluginRepositoryItem *> * _Nonnull availablePlugins) {
[self _fetchRepositoryDataCompletionHandler:^(NSArray<MPPluginRepositoryItem *> * _Nonnull availablePlugins) {
self.availablePlugins = availablePlugins;
self.isInitialized = YES;
}];
@@ -68,7 +69,7 @@ NSString *const MPPluginRepositoryDidUpdateAvailablePluginsNotification = @"com.
/* update cache on every read if it's older than 5 minutes */
if((NSDate.timeIntervalSinceReferenceDate - self.lastDataFetchTime) > 60*5 ) {
NSLog(@"%@: updating available plugins cache.", self.className);
[self fetchRepositoryDataCompletionHandler:^(NSArray<MPPluginRepositoryItem *> * _Nonnull availablePlugins) {
[self _fetchRepositoryDataCompletionHandler:^(NSArray<MPPluginRepositoryItem *> * _Nonnull availablePlugins) {
self.availablePlugins = availablePlugins;
}];
}
@@ -87,59 +88,91 @@ NSString *const MPPluginRepositoryDidUpdateAvailablePluginsNotification = @"com.
}
}
- (void)fetchRepositoryDataCompletionHandler:(void (^)(NSArray<MPPluginRepositoryItem *> * _Nonnull))completionHandler {
- (void)_fetchRepositoryDataCompletionHandler:(void (^)(NSArray<MPPluginRepositoryItem *> * _Nonnull))completionHandler {
BOOL allowRemoteConnection = [self _askForPluginRepositoryPermission];
if(!allowRemoteConnection) {
[self _fetchLocalFallbackRepositoryData:completionHandler];
return;
}
NSString *urlString = NSBundle.mainBundle.infoDictionary[MPBundlePluginRepositoryURLKey];
if(!urlString) {
if(completionHandler) {
completionHandler(@[]);
}
[self _fetchLocalFallbackRepositoryData:completionHandler];
return;
}
NSURL *jsonURL = [NSURL URLWithString:urlString];
if(!jsonURL) {
if(completionHandler) {
completionHandler(@[]);
}
[self _fetchLocalFallbackRepositoryData:completionHandler];
return;
}
NSURLSessionTask *downloadTask = [NSURLSession.sharedSession dataTaskWithURL:jsonURL completionHandler:^(NSData * _Nullable jsonData, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if(![response isKindOfClass:NSHTTPURLResponse.class]) {
if(completionHandler) {
completionHandler(@[]);
}
[self _fetchLocalFallbackRepositoryData:completionHandler];
return;
}
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if(httpResponse.statusCode != 200 || jsonData.length == 0) {
if(completionHandler) {
completionHandler(@[]);
}
[self _fetchLocalFallbackRepositoryData:completionHandler];
return;
}
id jsonRoot = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
if(!jsonRoot || ![jsonRoot isKindOfClass:NSArray.class]) {
if(completionHandler) {
completionHandler(@[]);
}
return;
}
NSMutableArray *items = [[NSMutableArray alloc] init];
for(id item in jsonRoot) {
if(![item isKindOfClass:NSDictionary.class]) {
continue;
}
MPPluginRepositoryItem *pluginItem = [MPPluginRepositoryItem pluginItemFromDictionary:item];
if(pluginItem.isVaid) {
[items addObject:pluginItem];
}
}
NSArray *items = [self _parseJSONData:jsonData];
if(completionHandler) {
completionHandler([items copy]);
}
}];
[downloadTask resume];
}
- (void)_fetchLocalFallbackRepositoryData:(void (^)(NSArray<MPPluginRepositoryItem *> * _Nonnull))completionHandler {
NSURL *jsonURL = [NSBundle.mainBundle URLForResource:@"plugins" withExtension:@"json"];
NSData *localJsonData = [NSData dataWithContentsOfURL:jsonURL];
if(!localJsonData) {
if(completionHandler) {
completionHandler(@[]);
}
}
NSArray<MPPluginRepositoryItem *> *items = [self _parseJSONData:localJsonData];
if(completionHandler) {
completionHandler(items);
}
}
- (NSArray<MPPluginRepositoryItem *> *)_parseJSONData:(NSData *)jsonData {
NSError *error;
id jsonRoot = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
if(!jsonRoot || ![jsonRoot isKindOfClass:NSArray.class]) {
return @[];
}
NSMutableArray *items = [[NSMutableArray alloc] init];
for(id item in jsonRoot) {
if(![item isKindOfClass:NSDictionary.class]) {
continue;
}
MPPluginRepositoryItem *pluginItem = [MPPluginRepositoryItem pluginItemFromDictionary:item];
if(pluginItem.isVaid) {
[items addObject:pluginItem];
}
}
return [items copy];
}
- (BOOL)_askForPluginRepositoryPermission {
if(![NSUserDefaults.standardUserDefaults objectForKey:kMPSettingsKeyAllowRemoteFetchOfPluginRepository]) {
NSAlert *alert = [[NSAlert alloc] init];
alert.alertStyle = NSAlertStyleWarning;
alert.informativeText = NSLocalizedString(@"ALERT_ASK_FOR_PLUGIN_REPOSITORY_CONNECTION_PERMISSION_INFORMATIVE_TEXT", @"Informative text displayed on the alert that shows up when MacPass asks for permssion to download the plugin repository JSON file");
alert.messageText = NSLocalizedString(@"ALERT_ASK_FOR_PLUGIN_REPOSITORY_CONNECTION_PERMISSION_MESSAGE", @"Message displayed on the alert that askf for permission to download the plugin repository JSON file");
alert.showsSuppressionButton = YES;
[alert addButtonWithTitle:NSLocalizedString(@"ALERT_ASK_FOR_PLUGIN_REPOSITORY_DISALLOW_DOWNLOAD", @"Disallow the download of the plugin repository file")];
[alert addButtonWithTitle:NSLocalizedString(@"ALERT_ASK_FOR_PLUGIN_REPOSITORY_ALLOW_DOWNLOAD", @"Allow the download of the plugin repository file")];
NSModalResponse repsonse = [alert runModal];
BOOL allow = (repsonse == NSAlertFirstButtonReturn);
[NSUserDefaults.standardUserDefaults setBool:allow forKey:kMPSettingsKeyAllowRemoteFetchOfPluginRepository];
return allow;
}
return [NSUserDefaults.standardUserDefaults boolForKey:kMPSettingsKeyAllowRemoteFetchOfPluginRepository];
}
@end

View File

@@ -87,6 +87,8 @@ APPKIT_EXTERN NSString *const kMPSettingsKeyLoadUnsecurePlugins; // I
APPKIT_EXTERN NSString *const kMPSettingsKeyDisabledPlugins; // NSArray of bundle identifiers of disabled plugins
APPKIT_EXTERN NSString *const kMPSettingsKeyLoadIncompatiblePlugins; // If set to YES incompatible plugins (no version info, marked as incompatible, etc) will be loaded regardless
APPKIT_EXTERN NSString *const kMPSettingsKeyHideIncopatiblePluginsWarning; // Do not show an alert, when MacPass encounteres incompatible plugins
APPKIT_EXTERN NSString *const kMPSettingsKeyAllowRemoteFetchOfPluginRepository; // Allow the download of the plugin repository file
APPKIT_EXTERN NSString *const kMPSettingsKeyPluginHideAksForRemoveConnectionPermission;
typedef NS_ENUM(NSUInteger, MPFileChangeStrategy) {
MPFileChangeStrategyAsk,

View File

@@ -84,6 +84,7 @@ NSString *const kMPSettingsKeyLoadUnsecurePlugins = @"LoadUn
NSString *const kMPSettingsKeyLoadIncompatiblePlugins = @"LoadIncompatiblePlugins";
NSString *const kMPSettingsKeyDisabledPlugins = @"DisabledPlugins";
NSString *const kMPSettingsKeyHideIncopatiblePluginsWarning = @"HideIncopatiblePluginsWarning";
NSString *const kMPSettingsKeyAllowRemoteFetchOfPluginRepository = @"AllowRemoteFetchOfPluginRepository";
/* Deprecated */
NSString *const kMPDeprecatedSettingsKeyRememberKeyFilesForDatabases = @"kMPSettingsKeyRememberKeyFilesForDatabases";

View File

@@ -0,0 +1,26 @@
[
{
"name": "MacPassHTTP",
"description": "KeePassHTTP support for MacPass",
"download": "https://github.com/MacPass/MacPassHTTP/releases/download/0.3.1/MacPassHTTP.mpplugin-0.3.1.zip",
"source": "https://github.com/MacPass/MacPassHTTP",
"currentVersion": "0.3.1",
"bundleIdentifier": "com.hicknhacksoftware.MacPassHTTP",
"compatibilty" : [
{
"pluginVersion": "0.2.*",
"minimumHostVersion" : "0.6.1",
"maximumHostVersion" : "0.6.2"
},
{
"pluginVersion": "0.3",
"minimumHostVersion" : "0.7",
"maximumHostVersion" : "0.7.3"
},
{
"pluginVersion": "0.3.1",
"minimumHostVersion" : "0.7.4"
}
]
}
]

View File

@@ -0,0 +1,6 @@
#!/bin/bash
URL="https://macpassapp.org/data/plugins.json"
MY_FOLDER="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
DOWNLOAD_FOLDER="${MY_FOLDER}/../MacPass/Resources/"
cd "${DOWNLOAD_FOLDER}"
wget "${URL}"