Browse Source

Projucer: Fix non-bool app sandbox temporary exception entitlements

v6.1.6
Tom Poole 3 years ago
parent
commit
dc4b9bd152
10 changed files with 136 additions and 24 deletions
  1. +16
    -0
      docs/CMake API.md
  2. +8
    -0
      extras/Build/CMake/JUCEUtils.cmake
  3. +15
    -1
      extras/Build/juce_build_tools/utils/juce_Entitlements.cpp
  4. +8
    -0
      extras/Build/juce_build_tools/utils/juce_Entitlements.h
  5. +23
    -0
      extras/Build/juceaide/Main.cpp
  6. +6
    -7
      extras/Projucer/Source/Project/UI/jucer_ContentViewComponents.h
  7. +49
    -7
      extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h
  8. +4
    -0
      extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h
  9. +5
    -7
      extras/Projucer/Source/Utility/UI/jucer_ProjucerLookAndFeel.cpp
  10. +2
    -2
      extras/Projucer/Source/Utility/UI/jucer_ProjucerLookAndFeel.h

+ 16
- 0
docs/CMake API.md View File

@@ -427,6 +427,22 @@ attributes directly to these creation functions, rather than adding them later.
plist if `APP_SANDBOX_ENABLED` is `TRUE`. Each key should be in the form `com.apple.security.*`
where `*` is a specific entitlement.

`APP_SANDBOX_FILE_ACCESS_HOME_RO`
- A set of space-separated paths that will be added to this target's entitlements plist for
accessing read-only paths relative to the home directory if `APP_SANDBOX_ENABLED` is `TRUE`.

`APP_SANDBOX_FILE_ACCESS_HOME_RW`
- A set of space-separated paths that will be added to this target's entitlements plist for
accessing read/write paths relative to the home directory if `APP_SANDBOX_ENABLED` is `TRUE`.

`APP_SANDBOX_FILE_ACCESS_ABS_RO`
- A set of space-separated paths that will be added to this target's entitlements plist for
accessing read-only absolute paths if `APP_SANDBOX_ENABLED` is `TRUE`.

`APP_SANDBOX_FILE_ACCESS_ABS_RW`
- A set of space-separated paths that will be added to this target's entitlements plist for
accessing read/write absolute paths if `APP_SANDBOX_ENABLED` is `TRUE`.

`PLIST_TO_MERGE`
- A string to insert into an app/plugin's Info.plist.



+ 8
- 0
extras/Build/CMake/JUCEUtils.cmake View File

@@ -318,6 +318,10 @@ function(_juce_write_configure_time_info target)
_juce_append_target_property(file_content APP_SANDBOX_INHERIT ${target} JUCE_APP_SANDBOX_INHERIT)
_juce_append_target_property(file_content HARDENED_RUNTIME_OPTIONS ${target} JUCE_HARDENED_RUNTIME_OPTIONS)
_juce_append_target_property(file_content APP_SANDBOX_OPTIONS ${target} JUCE_APP_SANDBOX_OPTIONS)
_juce_append_target_property(file_content APP_SANDBOX_FILE_ACCESS_HOME_RO ${target} JUCE_APP_SANDBOX_FILE_ACCESS_HOME_RO)
_juce_append_target_property(file_content APP_SANDBOX_FILE_ACCESS_HOME_RW ${target} JUCE_APP_SANDBOX_FILE_ACCESS_HOME_RW)
_juce_append_target_property(file_content APP_SANDBOX_FILE_ACCESS_ABS_RO ${target} JUCE_APP_SANDBOX_FILE_ACCESS_ABS_RO)
_juce_append_target_property(file_content APP_SANDBOX_FILE_ACCESS_ABS_RW ${target} JUCE_APP_SANDBOX_FILE_ACCESS_ABS_RW)
_juce_append_target_property(file_content APP_GROUPS_ENABLED ${target} JUCE_APP_GROUPS_ENABLED)
_juce_append_target_property(file_content APP_GROUP_IDS ${target} JUCE_APP_GROUP_IDS)
_juce_append_target_property(file_content IS_PLUGIN ${target} JUCE_IS_PLUGIN)
@@ -1546,6 +1550,10 @@ function(_juce_initialise_target target)
VST3_CATEGORIES
HARDENED_RUNTIME_OPTIONS
APP_SANDBOX_OPTIONS
APP_SANDBOX_FILE_ACCESS_HOME_RO
APP_SANDBOX_FILE_ACCESS_HOME_RW
APP_SANDBOX_FILE_ACCESS_ABS_RO
APP_SANDBOX_FILE_ACCESS_ABS_RW
DOCUMENT_EXTENSIONS
AAX_CATEGORY
IPHONE_SCREEN_ORIENTATIONS # iOS only


+ 15
- 1
extras/Build/juce_build_tools/utils/juce_Entitlements.cpp View File

@@ -79,7 +79,7 @@ namespace build_tools
if (isAppGroupsEnabled)
{
auto appGroups = StringArray::fromTokens (appGroupIdString, ";", {});
auto groups = String ("<array>");
String groups = "<array>";
for (auto group : appGroups)
groups += "\n\t\t<string>" + group.trim() + "</string>";
@@ -101,13 +101,27 @@ namespace build_tools
{
// no other sandbox options can be specified if sandbox inheritance is enabled!
jassert (appSandboxOptions.isEmpty());
jassert (appSandboxTemporaryPaths.empty());
entitlements.set ("com.apple.security.inherit", "<true/>");
}
if (isAppSandboxEnabled)
{
for (auto& option : appSandboxOptions)
entitlements.set (option, "<true/>");
for (auto& option : appSandboxTemporaryPaths)
{
String paths = "<array>";
for (const auto& path : option.values)
paths += "\n\t\t<string>" + path + "</string>";
paths += "\n\t</array>";
entitlements.set (option.key, paths);
}
}
}
if (isNetworkingMulticastEnabled)


+ 8
- 0
extras/Build/juce_build_tools/utils/juce_Entitlements.h View File

@@ -49,6 +49,14 @@ namespace build_tools
StringArray hardenedRuntimeOptions;
StringArray appSandboxOptions;
struct KeyAndStringArray
{
String key;
StringArray values;
};
std::vector<KeyAndStringArray> appSandboxTemporaryPaths;
private:
StringPairArray getEntitlements() const;
};


+ 23
- 0
extras/Build/juceaide/Main.cpp View File

@@ -343,6 +343,29 @@ juce::build_tools::EntitlementOptions parseEntitlementsOptions (const juce::File
updateField ("APP_SANDBOX_OPTIONS", result.appSandboxOptions);
updateField ("NETWORK_MULTICAST_ENABLED", result.isNetworkingMulticastEnabled);
struct SandboxTemporaryAccessKey
{
juce::String cMakeVar, key;
};
SandboxTemporaryAccessKey sandboxTemporaryAccessKeys[]
{
{ "APP_SANDBOX_FILE_ACCESS_HOME_RO", "home-relative-path.read-only" },
{ "APP_SANDBOX_FILE_ACCESS_HOME_RW", "home-relative-path.read-write" },
{ "APP_SANDBOX_FILE_ACCESS_ABS_RO", "absolute-path.read-only" },
{ "APP_SANDBOX_FILE_ACCESS_ABS_RW", "absolute-path.read-write" }
};
for (const auto& entry : sandboxTemporaryAccessKeys)
{
juce::StringArray values;
updateField (entry.cMakeVar, values);
if (! values.isEmpty())
result.appSandboxTemporaryPaths.push_back ({ "com.apple.security.temporary-exception.files." + entry.key,
std::move (values) });
}
result.type = type;
return result;


+ 6
- 7
extras/Projucer/Source/Project/UI/jucer_ContentViewComponents.h View File

@@ -302,8 +302,7 @@ public:
for (auto& pp : properties)
{
const auto propertyHeight = pp->getPreferredHeight()
+ (getHeightMultiplier (pp.get()) * pp->getPreferredHeight());
const auto propertyHeight = jmax (pp->getPreferredHeight(), getApproximateLabelHeight (*pp));
auto iter = std::find_if (propertyComponentsWithInfo.begin(), propertyComponentsWithInfo.end(),
[&pp] (const std::unique_ptr<PropertyAndInfoWrapper>& w) { return &w->propertyComponent == pp.get(); });
@@ -418,17 +417,17 @@ private:
}
}
int getHeightMultiplier (PropertyComponent* pp)
static int getApproximateLabelHeight (const PropertyComponent& pp)
{
auto availableTextWidth = ProjucerLookAndFeel::getTextWidthForPropertyComponent (pp);
auto font = ProjucerLookAndFeel::getPropertyComponentFont();
auto nameWidth = font.getStringWidthFloat (pp->getName());
if (availableTextWidth == 0)
return 0;
return static_cast<int> (nameWidth / (float) availableTextWidth);
const auto font = ProjucerLookAndFeel::getPropertyComponentFont();
const auto labelWidth = font.getStringWidthFloat (pp.getName());
const auto numLines = (int) (labelWidth / (float) availableTextWidth) + 1;
return (int) std::round ((float) numLines * font.getHeight() * 1.1f);
}
//==============================================================================


+ 49
- 7
extras/Projucer/Source/ProjectSaving/jucer_ProjectExport_Xcode.h View File

@@ -74,6 +74,10 @@ public:
appSandboxValue (settings, Ids::appSandbox, getUndoManager()),
appSandboxInheritanceValue (settings, Ids::appSandboxInheritance, getUndoManager()),
appSandboxOptionsValue (settings, Ids::appSandboxOptions, getUndoManager(), Array<var>(), ","),
appSandboxHomeDirROValue (settings, Ids::appSandboxHomeDirRO, getUndoManager()),
appSandboxHomeDirRWValue (settings, Ids::appSandboxHomeDirRW, getUndoManager()),
appSandboxAbsDirROValue (settings, Ids::appSandboxAbsDirRO, getUndoManager()),
appSandboxAbsDirRWValue (settings, Ids::appSandboxAbsDirRW, getUndoManager()),
hardenedRuntimeValue (settings, Ids::hardenedRuntime, getUndoManager()),
hardenedRuntimeOptionsValue (settings, Ids::hardenedRuntimeOptions, getUndoManager(), Array<var>(), ","),
microphonePermissionNeededValue (settings, Ids::microphonePermissionNeeded, getUndoManager()),
@@ -173,6 +177,21 @@ public:
bool isAppSandboxInhertianceEnabled() const { return appSandboxInheritanceValue.get(); }
Array<var> getAppSandboxOptions() const { return *appSandboxOptionsValue.get().getArray(); }
auto getAppSandboxTemporaryPaths() const
{
std::vector<build_tools::EntitlementOptions::KeyAndStringArray> result;
for (const auto& entry : sandboxFileAccessProperties)
{
auto paths = getCommaOrWhitespaceSeparatedItems (entry.property.get());
if (! paths.isEmpty())
result.push_back ({ "com.apple.security.temporary-exception.files." + entry.key, std::move (paths) });
}
return result;
}
Array<var> getValidArchs() const { return *validArchsValue.get().getArray(); }
bool isMicrophonePermissionEnabled() const { return microphonePermissionNeededValue.get(); }
@@ -457,29 +476,36 @@ public:
{ "Temporary Exception: Audio Unit Hosting", "temporary-exception.audio-unit-host" },
{ "Temporary Exception: Global Mach Service", "temporary-exception.mach-lookup.global-name" },
{ "Temporary Exception: Global Mach Service Dynamic Registration", "temporary-exception.mach-register.global-name" },
{ "Temporary Exception: Home Directory File Access (Read Only)", "temporary-exception.files.home-relative-path.read-only" },
{ "Temporary Exception: Home Directory File Access (Read/Write)", "temporary-exception.files.home-relative-path.read-write" },
{ "Temporary Exception: Absolute Path File Access (Read Only)", "temporary-exception.files.absolute-path.read-only" },
{ "Temporary Exception: Absolute Path File Access (Read/Write)", "temporary-exception.files.absolute-path.read-write" },
{ "Temporary Exception: IOKit User Client Class", "temporary-exception.iokit-user-client-class" },
{ "Temporary Exception: Shared Preference Domain (Read Only)", "temporary-exception.shared-preference.read-only" },
{ "Temporary Exception: Shared Preference Domain (Read/Write)", "temporary-exception.shared-preference.read-write" }
};
StringArray sandboxKeys;
Array<var> sanboxValues;
Array<var> sandboxValues;
for (auto& opt : sandboxOptions)
{
sandboxKeys.add (opt.first);
sanboxValues.add ("com.apple.security." + opt.second);
sandboxValues.add ("com.apple.security." + opt.second);
}
props.add (new MultiChoicePropertyComponentWithEnablement (appSandboxOptionsValue,
appSandboxValue,
"App Sandbox Options",
sandboxKeys,
sanboxValues));
sandboxValues));
for (const auto& entry : sandboxFileAccessProperties)
{
props.add (new TextPropertyComponentWithEnablement (entry.property,
appSandboxValue,
entry.label,
8192,
true),
"A list of the corresponding paths (separated by newlines or whitespace). "
"See Apple's File Access Temporary Exceptions documentation.");
}
props.add (new ChoicePropertyComponent (hardenedRuntimeValue, "Use Hardened Runtime"),
"Enable this to use the hardened runtime required for app notarization.");
@@ -3085,6 +3111,7 @@ private:
options.appGroupIdString = getAppGroupIdString();
options.hardenedRuntimeOptions = getHardenedRuntimeOptions();
options.appSandboxOptions = getAppSandboxOptions();
options.appSandboxTemporaryPaths = getAppSandboxTemporaryPaths();
const auto entitlementsFile = getTargetFolder().getChildFile (target.getEntitlementsFilename());
build_tools::overwriteFileIfDifferentOrThrow (entitlementsFile, options.getEntitlementsFileContent());
@@ -3566,6 +3593,7 @@ private:
duplicateAppExResourcesFolderValue, iosDeviceFamilyValue, iPhoneScreenOrientationValue,
iPadScreenOrientationValue, customXcodeResourceFoldersValue, customXcassetsFolderValue,
appSandboxValue, appSandboxInheritanceValue, appSandboxOptionsValue,
appSandboxHomeDirROValue, appSandboxHomeDirRWValue, appSandboxAbsDirROValue, appSandboxAbsDirRWValue,
hardenedRuntimeValue, hardenedRuntimeOptionsValue,
microphonePermissionNeededValue, microphonePermissionsTextValue,
cameraPermissionNeededValue, cameraPermissionTextValue,
@@ -3576,5 +3604,19 @@ private:
networkingMulticastValue, iosDevelopmentTeamIDValue, iosAppGroupsIDValue, keepCustomXcodeSchemesValue, useHeaderMapValue, customLaunchStoryboardValue,
exporterBundleIdentifierValue, suppressPlistResourceUsageValue, useLegacyBuildSystemValue, buildNumber;
struct SandboxFileAccessProperty
{
const ValueTreePropertyWithDefault& property;
const String label, key;
};
const std::vector<SandboxFileAccessProperty> sandboxFileAccessProperties
{
{ appSandboxHomeDirROValue, "App sandbox temporary exception: home directory read only file access", "home-relative-path.read-only" },
{ appSandboxHomeDirRWValue, "App sandbox temporary exception: home directory read/write file access", "home-relative-path.read-write" },
{ appSandboxAbsDirROValue, "App sandbox temporary exception: absolute path read only file access", "absolute-path.read-only" },
{ appSandboxAbsDirRWValue, "App sandbox temporary exception: absolute path read/write file access", "absolute-path.read-write" }
};
JUCE_DECLARE_NON_COPYABLE (XcodeProjectExporter)
};

+ 4
- 0
extras/Projucer/Source/Utility/Helpers/jucer_PresetIDs.h View File

@@ -196,6 +196,10 @@ namespace Ids
DECLARE_ID (appSandbox);
DECLARE_ID (appSandboxInheritance);
DECLARE_ID (appSandboxOptions);
DECLARE_ID (appSandboxHomeDirRO);
DECLARE_ID (appSandboxHomeDirRW);
DECLARE_ID (appSandboxAbsDirRO);
DECLARE_ID (appSandboxAbsDirRW);
DECLARE_ID (hardenedRuntime);
DECLARE_ID (hardenedRuntimeOptions);
DECLARE_ID (microphonePermissionNeeded);


+ 5
- 7
extras/Projucer/Source/Utility/UI/jucer_ProjucerLookAndFeel.cpp View File

@@ -94,23 +94,21 @@ int ProjucerLookAndFeel::getTabButtonBestWidth (TabBarButton& button, int)
return 120;
}
void ProjucerLookAndFeel::drawPropertyComponentLabel (Graphics& g, int width, int height, PropertyComponent& component)
void ProjucerLookAndFeel::drawPropertyComponentLabel (Graphics& g, int, int height, PropertyComponent& component)
{
ignoreUnused (width);
g.setColour (component.findColour (defaultTextColourId)
.withMultipliedAlpha (component.isEnabled() ? 1.0f : 0.6f));
auto textWidth = getTextWidthForPropertyComponent (&component);
auto textWidth = getTextWidthForPropertyComponent (component);
g.setFont (getPropertyComponentFont());
g.drawFittedText (component.getName(), 0, 0, textWidth - 5, height, Justification::centredLeft, 5, 1.0f);
g.drawFittedText (component.getName(), 0, 0, textWidth, height, Justification::centredLeft, 5, 1.0f);
}
Rectangle<int> ProjucerLookAndFeel::getPropertyComponentContentPosition (PropertyComponent& component)
{
const auto textW = getTextWidthForPropertyComponent (&component);
return { textW, 0, component.getWidth() - textW, component.getHeight() - 1 };
const auto paddedTextW = getTextWidthForPropertyComponent (component) + 5;
return { paddedTextW , 0, component.getWidth() - paddedTextW, component.getHeight() - 1 };
}
void ProjucerLookAndFeel::drawButtonBackground (Graphics& g,


+ 2
- 2
extras/Projucer/Source/Utility/UI/jucer_ProjucerLookAndFeel.h View File

@@ -81,8 +81,8 @@ public:
const bool filled, const Justification justification);
static Path getChoiceComponentArrowPath (Rectangle<float> arrowZone);
static Font getPropertyComponentFont() { return { 14.0f, Font::FontStyleFlags::bold }; }
static int getTextWidthForPropertyComponent (PropertyComponent* pp) { return jmin (200, pp->getWidth() / 2); }
static Font getPropertyComponentFont() { return { 14.0f, Font::FontStyleFlags::bold }; }
static int getTextWidthForPropertyComponent (const PropertyComponent& pc) { return jmin (200, pc.getWidth() / 2); }
static ColourScheme getProjucerDarkColourScheme()
{


Loading…
Cancel
Save