From 6477ae394e83b8776695c6937375bbcde7388605 Mon Sep 17 00:00:00 2001 From: Robert Sesek Date: Sat, 7 Dec 2019 17:42:56 -0500 Subject: [PATCH] Add a new File Access preferences pane. Doing file access on a per-bookmark basis does not work well. When debugging a local file and a file-line breakpoint were added from the source view of a stack frame, the user would not be able to then view the breakpoint in context by selecting it from the breakpoints panel. Instead, the file access prefs will be used to grant access to directory subtrees. --- Source/AppDelegate.m | 41 +++++++++++ Source/PreferenceNames.h | 3 + Source/PreferenceNames.m | 2 + Source/PreferencesController.h | 7 ++ Source/PreferencesController.m | 36 ++++++++++ en.lproj/Preferences.xib | 126 ++++++++++++++++++++++++++++----- 6 files changed, 199 insertions(+), 16 deletions(-) diff --git a/Source/AppDelegate.m b/Source/AppDelegate.m index fdf1cd9..e665c35 100644 --- a/Source/AppDelegate.m +++ b/Source/AppDelegate.m @@ -37,6 +37,7 @@ kPrefPort : @9000, kPrefInspectorWindowVisible : @YES, kPrefPathReplacements : [NSMutableArray array], + kPrefFileAccessBookmarks : [NSMutableDictionary dictionary], kPrefBreakOnFirstLine : @YES, kPrefDebuggerAttached : @YES, kPrefSelectedDebuggerSegment : @1, @@ -62,6 +63,8 @@ usesUnstable = usesUnstable || [[feedURL absoluteString] rangeOfString:@"?unstable"].location != NSNotFound; [defaults setBool:usesUnstable forKey:kPrefUnstableVersionCast]; + + [self _activateSecureFileAccess]; } - (void)applicationWillTerminate:(NSNotification*)notification @@ -107,4 +110,42 @@ [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://www.bluestatic.org/software/macgdbp/help/"]]; } +/** + * Activates any secure file access bookmarks stored in preferences. + */ +- (void)_activateSecureFileAccess +{ + NSDictionary* prefs = [NSUserDefaults.standardUserDefaults objectForKey:kPrefFileAccessBookmarks]; + NSMutableDictionary* bookmarks = [NSMutableDictionary dictionaryWithDictionary:prefs]; + for (NSString* path in bookmarks) { + NSURL* url = [NSURL URLWithString:path]; + + BOOL isStale; + NSError* error; + url = [NSURL URLByResolvingBookmarkData:bookmarks[path] + options:NSURLBookmarkResolutionWithSecurityScope + relativeToURL:nil + bookmarkDataIsStale:&isStale + error:&error]; + if (error) { + NSLog(@"Failed to resolve secure bookmark for path %@: %@", path, error); + continue; + } + if (isStale) { + NSData* newBookmark = [url bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope | NSURLBookmarkCreationSecurityScopeAllowOnlyReadAccess + includingResourceValuesForKeys:nil + relativeToURL:nil + error:&error]; + bookmarks[path] = newBookmark; + } + + if (![url startAccessingSecurityScopedResource]) { + NSLog(@"Failed to start accessing resource %@", path); + continue; + } + } + + [NSUserDefaults.standardUserDefaults setObject:bookmarks forKey:kPrefFileAccessBookmarks]; +} + @end diff --git a/Source/PreferenceNames.h b/Source/PreferenceNames.h index 92c4b50..fa6b777 100644 --- a/Source/PreferenceNames.h +++ b/Source/PreferenceNames.h @@ -25,6 +25,9 @@ extern NSString* const kPrefInspectorWindowVisible; // NSMutableArray of path replacements. extern NSString* const kPrefPathReplacements; +// NSMutableDictionary of NSString paths to NSData file access bookmarks. +extern NSString* const kPrefFileAccessBookmarks; + // NSNumber bool for whether to stop the debugger on the first line of the // program. extern NSString* const kPrefBreakOnFirstLine; diff --git a/Source/PreferenceNames.m b/Source/PreferenceNames.m index c58c91a..49da56b 100644 --- a/Source/PreferenceNames.m +++ b/Source/PreferenceNames.m @@ -22,6 +22,8 @@ NSString* const kPrefInspectorWindowVisible = @"InspectorWindowVisible"; NSString* const kPrefPathReplacements = @"PathReplacements"; +NSString* const kPrefFileAccessBookmarks = @"FileAccessBookmarks"; + NSString* const kPrefBreakOnFirstLine = @"BreakOnFirstLine"; NSString* const kPrefDebuggerAttached = @"DebuggerAttached"; diff --git a/Source/PreferencesController.h b/Source/PreferencesController.h index 9c37f1a..dd7da37 100644 --- a/Source/PreferencesController.h +++ b/Source/PreferencesController.h @@ -24,13 +24,20 @@ @property (strong) IBOutlet NSView* generalPreferencesView; @property (strong) IBOutlet NSToolbarItem* generalPreferencesItem; +@property (strong) IBOutlet NSDictionaryController* fileAccessController; +@property (strong) IBOutlet NSView* fileAccessPreferencesView; +@property (strong) IBOutlet NSToolbarItem* fileAccessPreferencesItem; + @property (strong) IBOutlet NSView* pathsPreferencesView; @property (strong) IBOutlet NSToolbarItem* pathsPreferencesItem; - (void)showPreferencesWindow; +- (IBAction)addFileAccess:(id)sender; + // panel switching - (IBAction)showGeneral:(id)sender; +- (IBAction)showFileAccess:(id)sender; - (IBAction)showPaths:(id)sender; @end diff --git a/Source/PreferencesController.m b/Source/PreferencesController.m index dae6a8f..ae64402 100644 --- a/Source/PreferencesController.m +++ b/Source/PreferencesController.m @@ -43,6 +43,36 @@ [window makeKeyAndOrderFront:self]; } +/** + * Brings up a file picker to grant read-only file access to the selected path, + * which is then persisted across application restarts. + */ +- (IBAction)addFileAccess:(id)sender +{ + NSOpenPanel* panel = [NSOpenPanel openPanel]; + panel.canChooseDirectories = YES; + panel.canChooseFiles = NO; + if ([panel runModal] != NSOKButton) + return; + + NSURL* url = panel.URL; + + NSError* error; + NSData* secureBookmark = [url bookmarkDataWithOptions:NSURLBookmarkCreationWithSecurityScope | NSURLBookmarkCreationSecurityScopeAllowOnlyReadAccess + includingResourceValuesForKeys:nil + relativeToURL:nil + error:&error]; + if (error) { + NSLog(@"Error creating secure bookmark: %@", error); + return; + } + + NSDictionaryControllerKeyValuePair* pair = [self.fileAccessController newObject]; + pair.key = url.absoluteString; + pair.value = secureBookmark; + [self.fileAccessController addObject:pair]; +} + #pragma mark Panel Switching /** @@ -53,6 +83,11 @@ [self _switchToView:self.generalPreferencesView forToolbarItem:self.generalPreferencesItem]; } +- (IBAction)showFileAccess:(id)sender +{ + [self _switchToView:self.fileAccessPreferencesView forToolbarItem:self.fileAccessPreferencesItem]; +} + /** * Shows the path replacement panel */ @@ -70,6 +105,7 @@ { return @[ self.generalPreferencesItem.itemIdentifier, + self.fileAccessPreferencesItem.itemIdentifier, self.pathsPreferencesItem.itemIdentifier, ]; } diff --git a/en.lproj/Preferences.xib b/en.lproj/Preferences.xib index 2dd5af2..ee75cb4 100644 --- a/en.lproj/Preferences.xib +++ b/en.lproj/Preferences.xib @@ -1,13 +1,16 @@ - + - + + + + @@ -22,10 +25,10 @@ - + - + @@ -36,7 +39,12 @@ - + + + + + + @@ -44,6 +52,7 @@ + @@ -52,13 +61,14 @@ + - + @@ -67,7 +77,7 @@ - - + @@ -87,7 +97,7 @@ - + @@ -100,7 +110,7 @@ - + @@ -110,12 +120,13 @@ + - - - + - + - + @@ -201,7 +212,13 @@ + + + + + + local @@ -216,10 +233,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + -- 2.22.5