How to read mac system preferences programmatically? - macos

I'm trying to tell if a user has specific system preferences set. I.e. the app needs to know if they've given Full Disk Access, if they've selected our app under Accessibility, etc. like in the picture below.
I know we can do something like
defaults read com.apple.AppleMultitouchTrackpad
but I'm having trouble finding this out for Full Disk Access, Files and Folders, and Accessibility under Security & Privacy.
Is there a list of the com.apple.XXX somewhere?
I'm basically trying to do something like
defaults read com.apple.security.Privacy_Accessibility
I'm able to open the system preferences pane with electron like
shell.openExternal('x-apple.systempreferences:com.apple.preference.security.Privacy_Accessibility')
So I thought there might be a way similar to this for reading the settings.

To determine if accessibility access is enabled, you can use AXIsProcessTrusted and it's counterpart, AXIsProcessTrustedWithOptions. Both are part of ApplicationServices. From the documentation:
Returns TRUE if the current process is a trusted accessibility client, FALSE if it is not.
It doesn't seem possible to detect if FDA is enabled or not; there is no API for that. Some developers try to test access by attempting to read a known protected file and seeing if that works or not; but this approach is fragile and Apple does recommend against it. More discussion here.

Related

Programmatically enable (or disable) AppleScript support for an application

I have an App Store app in which the free version is not scriptable, but the premium version is. AppleScript support is one of the key differences. I know the App Store reviewers are pushing more and more towards free + in-app-purchase, which will help declutter the App Store. Fine, I'll play ball.
Now I need to do something programmatically that I've always just worked into the build.
Is there a way to disable AppleScript if my OSAScriptingDefinition and NSAppleScriptEnabled are set in my Info.plist? This would still allow people to open the dictionary, and maybe they'd like what they see and consider activating the upgrade. Or,
Is there a way to enable AppleScript after the fact? Obviously with code-signing, I can't do things like modify Info.plist, or add my SDEF to the bundle later. But maybe if the SDEF were in a non-standard location, I could load it from the bundle and tell the system about it manually.
Does the SDEF have to live in my bundle? If not, I'm not sure how to point to the user's Application Support directory in the sandbox. I've also considered xinclude an SDEF I can install after the fact, but again, the SDEF and plist require actual directory paths and not functions.
I've tried a couple of things such as attempting to set NSScriptSuiteRegistry's singleton to nil, to no effect.
Because OSAScriptingDefinition and NSAppleScriptEnabled enable "automatic" support, surely there must be a manual way to make them to effect if not in the plist, and hopefully with a public API.
Any ideas here? Thanks!
A few points, for orientation:
All AppleScript commands are subclasses of NSScriptCommand
All AppleScript objects are represented by subclasses of
NSScriptObjectSpecifier
The scriptability of an app is controlled by its shared instance of NSScriptSuiteRegistry
This gives you a few options. You could try, for instance, overriding NSScriptSuiteRegistry setSharedScriptSuiteRegistry: and setting it to nil for the free version. You could also write a category on NSScriptCommand and/or NSScriptObjectSpecifier that does a version check. That would give you fine-grained control: you could call it from any methods that handle a script command or returns a script object, and decide on the fly which you want to allow and which you want to block; maybe even pop up a 'Pay for Full AppleScript Access' dialog.
CocoaScripting is a black box and not very adaptable. Simplest (kludgy) solution would be to wait until CS has installed its Apple event handlers then call -[NSAppleEventManager setEventHandler:andSelector:forEventClass:andEventID:] to replace those with a dummy handler that always sends back a "requires in-app purchase" error. (Don’t replace the standard open, quit, etc. handlers obviously.)

Is it possible to access file system in Mac App without file browser dialogue

In our Mac App we have following credential to entitlement.plist which enables us to read/write to user's file system followed by file browser dialogue:
com.apple.security.files.user-selected.read-write
That does mean we able to read/write a file/folder if once accessed by file browser dialogue. We never able to read/write to files/folder if not accessed by file browser dialogue at least once in an application life cycle.
I didn't found any other possible credential too to entitlement.plist which can enable us read/write to files/folder by completely removing any use of file browser dialogue. Is there any way we can achieve this?
I assume your app is Sandboxed and if so, it's only possible to access the filesystem as defined here:
Powerbox and File System Access Outside of Your Container Your
sandboxed app can access file system locations outside of its
container in the following three ways:
At the specific direction of the user
By using entitlements for
specific file-system locations (described in Entitlements and System
Resource Access)
When the file system location is in certain
directories that are world readable
The OS X security technology that interacts with the user to expand your sandbox is called Powerbox. Powerbox has no API. Your app uses Powerbox transparently when you use the NSOpenPanel and NSSavePanel classes.
Well, the whole point of Sandboxing is to actually don't allow you to access user's files without their knowledge.
The only thing you can probably do is to use com.apple.security.temporary-exception.files.absolute-path.* entitlements to access some specific (read hard-coded) file system locations. You can learn more about temporary exceptions here: App Sandbox Temporary Exception Entitlements.
But keep in mind that you'll have to explain to the Apple Review Team why you need those exceptions in the first place.

How to access the Firefox preferences hash table?

Does anyone know how I could access the Firefox preferences hash table when it is running? I want to see what preferences exist in the hash table.
I'm pretty sure it's not possible to programmatically (via web) access about:config preferences. I've found this answer, where Wesley tells the same. I couldn't yet find it in documentation that it's not possible, but I'm sure it is. If it is possible - it's a bug. A critical one.
If a browser allowed this - it would be a huge security leak. Such configs might contain vulnerable data, possibly private or even embarrasing. For example browser.newtabpage.blocked pref contains blocked about:newtab sites, a trace of user's history.
It is however possible to access preferences when driving firefox by an external software, that interacts with firefox UI. It is then perfectly OK, because a user has to initiate such an action.

What elements should I include in a Mac Preferences Panel?

I have a question about my Mac program's preferences window. I have an application with a CoreData-based back end. My program includes a feature that allows users to switch out the database for a different one. I do not expect users to do this very often—perhaps once or twice a year.
Now, many of the options that users can tweak are stored in the database. These options need to be configured once every time that a new database is used, because they are specific to the database itself.
The Apple Human Interface Guidelines on Preferences state this:
As much as possible, ensure that users rarely need to reset
preferences. Ideally, preferences include settings that users might
want to change only once. If there are settings users might want to
change every time they open your app, or every time they perform a
certain task, don’t put these settings in preferences. Instead, you
could use a menu item or a control in a panel to gives user modeless
access to these settings.
My question is this: Are my database-level settings valid candidates for the preferences window? Does "once or twice a year" count as "rarely"? If not, are there any downsides to creating a second panel (with many panes that are controlled by an NSToolbar) that looks just like a preferences panel but is accessed from a different menu item ("Database Preferences" for example)?
I see database-level settings all the time under Preferences in various apps (1Password and MacJournal come to mind). Thus, Preferences often contains both database-level settings and "actual" preferences that go in a plist file. The former (the data-base level settings) is absolutely crucial, being the actual data. The latter (the plist file) isn't as important and losing this data shouldn't cause too much harm, as it's just simple settings the user can easily get back to manually.
On the other hand, I see nothing wrong with separating the two, especially if your app is a multi-window (document-based) app that can have many databases open at once.
But I do think it's simplest to just put it all into the Preferences. That's what you probably should do, unless you have a good reason to do otherwise.
To answer some of your questions directly:
Are my database-level settings valid candidates for the preferences window?
— Yeah, I think they are. And many apps (such as 1Password and MacJournal) do this too.
Does "once or twice a year" count as "rarely"?
— Yeah.
Are there any downsides to creating a second panel?
— If you have a good reason to separate the two, I see nothing wrong with it.
Just my two cents.

Programmatically Change System Network (Proxy) settings

Is there a way, from within a Cocoa application to change the system network settings (specifically, the proxy settings). I've found that there is a file called preferences.plist in /Library/Preferences/SystemConfiguration that has the settings I want, but I can't figure out how to get the system to process changes to this file without rebooting.
Can this be done programmatically, or at least by launching some command? (This solution would probably be 10.5.x only, I'm assuming)
Since I can change these settings in System Preferences immediately, there must be some way, it just eludes me ....
Thanks!
You want the SystemConfiguration framework, specifically the Proxies Dictionary (see here for more details).

Resources