Added support for alternate TokenStore implementations#1
Conversation
Added support to LicensingConfiguration to allow for specifying what kind of token store is used. Updated AmoreLicensing to use the configuration changes to setup the new token stores. Added support for App Groups to FileTokenStore. Added a new KeychainTokenStore that will load/save/delete from the macOS keychain.
|
First of all, thank you so much for your work on this. This is the first PR on this repository and it means a lot to me. ❤️ Your writeup is excellent and your investigation is spot on. I went with the alternative you suggested and made the Your Closing this in favor of #2, but the credit for the direction is yours. Thanks again ❤️ |
|
I suspected #2 would be the best way forward for you, glad that worked out. I also appreciate the credit! Since this repo and Pomodoro are MIT licensed, feel free to add code from this closed PR as sample code that may help someone else out. |
I have an application and a QuickLook extension that need to both validate the users license. The QuickLook extension is what people are mostly going to use and the most important thing, the application is primarily the delivery vehicle.
QuickLook extensions are heavily sandboxed, so I explored different storage methods until I found something that worked, the keychain. I tried other directories and App Groups but those were inaccessible from the extension.
This PR introduces support for the user to specify the token store location via a new
TokenStoreLocationenum inLicensingConfiguration. Options include:defaultLocation: The classic implementation. Default value for theLicensingConfigurationinitializer.directory(URL): A caller specified directory.appGroup(String): An App Group identifier.keychainAccessGroup(String): A keychain Access Group.Only minor changes were needed beyond that.
AmoreLicensing.initnow switches on the token store location to setup and appropriate store.FileTokenStorereceived a new initializer to use an App Group.KeychainTokenStore.swiftwas added to support the keychain.KeychainTokenStoresupports retrieve/store/delete. The queries are configured to allow access after first unlock, restrict the item to this device only (no iCloud sync), and the "data protection" keychain (the "login" keychain in Keychain Access). That last part is important as it's the only keychain extensions can access. Without that items are stored in the "Local Items" or "iCloud" keychain which is inaccessible from extensions.With these changes I can add/validate/delete licenses in the app, and validate the license from the extension.
All that said, the only method I need for my use case is keychain support. If you don't want to add support for the other included methods, those could be easily deleted.
An alternative implementation would be to make the
TokenStoreprotocol public and allow the caller to pass in their own implementation, thus relieving you of having to maintain additional code.Unfortunately, it is not possible (as far as I know) to unit test the App Group or Access Group solutions from a pure swift package setup. Those methods require the test host app to have specific entitlements configured, and package unit tests are hosted by Xcode in a generic faceless app that is the same for all packages.
It should be possible to add unit tests to the Pomodoro test app if that was desired.