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