RFR 7199674: (props) user.home property does not return an accessible location in sandboxed environment [macosx]
David DeHaven
david.dehaven at oracle.com
Tue Sep 10 22:36:32 UTC 2013
> I use user.home to do things like:
>
> String userHomePath = System.getProperty("user.home");
> myFileDialog.setDirectory(userHomePath + "/Documents");
This will continue to work fine. Like I said, user.home is the Data directory inside the app container which is a shadow of the users home folder, complete with symlinks to common user directories (such as Documents, Movies, Music, etc..). Sandboxd and powerbox manage all the translations behind the scene.
> In my app, the user selects where he wants to export individual files, such as CSVs and PDFs. These are files he'll use outside of my app.
>
> If user.home points to the app's sandbox Container, it will break this usage. Opening a file dialog to /Users/Bob/Library/Containers/my.app/Data/Documents will definitely confuse the user and if they save a file there, they will never be able to find it later from outside of my app.
The user won't know the difference, all they'll see is ~/Documents as provided by powerbox.
Fun fact: The reason powerbox isn't hackable is it runs in a separate process...
> Yes, I understand the whole sandboxing concept. I'm not asking for unrestricted access to the file system. I use the "com.apple.security.files.user-selected.read-write" entitlement so that the user can select where he wants to save files, and I want to present him with a standard, well-known, default location for that (like ~/Documents).
>
> If user.home doesn't point to the user's actual home folder (i.e. NSHomeDirectoryForUser), it makes creating a standard, well-known location path (like ~/Documents) much more difficult. (And IMHO, it breaks the definition of the user.home property: "User home directory", not "App home directory".)
Powerbox solves exactly that problem... and yes, yes it is users home folder, from the perspective of a sandboxed application!
Here's some code to prove it actually works since you don't seem to believe me:
{
@autorelease {
NSOpenPanel *panel = [NSOpenPanel openPanel];
panel.allowsMultipleSelection = NO;
panel.canChooseDirectories = NO;
NSString *home = NSHomeDirectory();
NSString *docs = [home stringByAppendingPathComponent:@"Downloads"];
NSLog(@"home: %@", home);
NSLog(@"docs: %@", docs);
[panel setDirectoryURL:[NSURL fileURLWithPath:docs]];
[panel beginWithCompletionHandler:^(NSInteger result) {
NSLog(@"panel result: %ld", result);
if (result == NSFileHandlingPanelOKButton) {
NSLog(@"panel selected file: %@", [[panel URLs] objectAtIndex:0]);
}
}];
}
}
Example run:
2013-09-10 15:30:52.630 BlahText[11480:303] home: /Users/daved/Library/Containers/com.blah.SomeApp/Data
2013-09-10 15:30:52.631 BlahText[11480:303] docs: /Users/daved/Library/Containers/com.blah.SomeApp/Data/Documents
2013-09-10 15:30:59.180 BlahText[11480:303] panel result: 1
2013-09-10 15:30:59.180 BlahText[11480:303] panel selected file: file://localhost/Users/daved/Documents/Some%20Document.txt
And the open panel opens displaying the contents of my Documents folder, the user will never see the app container path unless you explicitly report it to them.
-DrD-
More information about the core-libs-dev
mailing list