8000 fix(testflight): model automatic internal group access by shroominic · Pull Request #83 · shroominic/OpenGlucose · GitHub
[go: up one dir, main page]

Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion openhealth/fastlane/Fastfile
Original file line number Diff line number Diff line change
Expand Up @@ -272,9 +272,24 @@ def disable_automatic_notification(build)
end

def associated_groups(app:, build:)
app.get_beta_groups.select do |group|
groups = app.get_beta_groups
associated = groups.select do |group|
group.fetch_builds.any? { |candidate| candidate.id == build.id }
end

# App Store Connect grants an automatic internal group access to every build,
# but Fastlane's group.fetch_builds relationship can omit that implicit access.
# Add every automatic internal group so callers can reject any unapproved
# access. All other group access must remain explicit.
automatic_internal_groups = groups.select do |group|
group.is_internal_group == true && group.has_access_to_all_builds == true
end
automatic_internal_groups.each do |group|
associated << group unless associated.any? do |candidate|
candidate.id == group.id
end
end
associated
end

def require_exact_external_association(
Expand Down
84 changes: 83 additions & 1 deletion scripts/test-internal-testflight-policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,9 @@ def assert_rejected(message)

Build = Struct.new(:id)
build = Build.new("build-id")
approved.builds = [build]
# App Store Connect grants automatic internal-group access to every build, but
# Fastlane's group.fetch_builds relation can omit that implicit association.
approved.builds = []
approved_external.builds = [build]
associated = require_exact_external_association(
app: App.new([approved, approved_external]),
Expand All @@ -213,6 +215,38 @@ def assert_rejected(message)
"external build audience was not exact"
)

assert_rejected("wrong approved internal group ID in external audience") do
require_exact_external_association(
app: App.new([approved, approved_external]),
build: build,
approved_group: approved_external,
approved_internal_group_id: "wrong-group",
required: true
)
end

require_exclusive_internal_association(
app: App.new([approved]),
build: build,
approved_group: approved
)

# The automatic group can also be returned explicitly. It must not appear
# twice in the effective audience.
approved.builds = [build]
associated = require_exact_external_association(
app: App.new([approved, approved_external]),
build: build,
approved_group: approved_external,
approved_internal_group_id: approved.id,
required: true
)
assert(
associated.map(&:id).sort == [approved.id, approved_external.id].sort,
"explicit automatic group access was duplicated"
)
approved.builds = []

assert_rejected("unexpected associated group") do
unexpected = Group.new(
id: "unexpected-group",
Expand All @@ -231,6 +265,40 @@ def assert_rejected(message)
)
end

assert_rejected("unexpected implicit automatic internal group") do
unexpected_automatic_internal = Group.new(
id: "unexpected-automatic-internal",
name: "unexpected",
is_internal_group: true,
has_access_to_all_builds: true,
public_link_enabled: false,
builds: []
)
require_exact_external_association(
app: App.new([approved, approved_external, unexpected_automatic_internal]),
build: build,
approved_group: approved_external,
approved_internal_group_id: approved.id,
required: true
)
end

assert_rejected("unexpected implicit automatic internal group in internal release") do
unexpected_automatic_internal = Group.new(
id: "unexpected-automatic-internal",
name: "unexpected",
is_internal_group: true,
has_access_to_all_builds: true,
public_link_enabled: false,
builds: []
)
require_exclusive_internal_association(
app: App.new([approved, unexpected_automatic_internal]),
build: build,
approved_group: approved
)
end

assert(
exact_internal_automatic_group(
app: App.new([approved]),
Expand Down Expand Up @@ -276,4 +344,18 @@ def assert_rejected(message)
)
end

assert_rejected("unapproved automatic internal group") do
unexpected = Group.new(
id: "unexpected-automatic-internal",
name: "unexpected",
is_internal_group: true,
has_access_to_all_builds: true
)
exact_internal_automatic_group(
app: App.new([approved, unexpected]),
group_name: "team",
group_id: "approved-group"
)
end

puts "Internal TestFlight policy helper checks passed."
0