Skip to content
Draft
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
13 changes: 12 additions & 1 deletion lib/entitlements/service/github.rb
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ def initialize(addr: nil, org:, token:, ou:, ignore_not_found: false)
# need to be obtained only one time per organization, but might be used multiple times.
Entitlements.cache[:github_pending_members] ||= {}
Entitlements.cache[:github_org_members] ||= {}
Entitlements.cache[:github_enterprise] ||= {}
end

# Return the identifier, either the address specified or otherwise "github.com".
Expand Down Expand Up @@ -97,13 +98,23 @@ def org_members
end

# Returns true if the github instance is an enterprise server instance
#
# Whether an instance is GHES is a property of the instance and not of any one organization,
# so this is cached against the address rather than the org signature. Without this the meta
# endpoint is queried once per organization, which is a request per org for an answer that
# cannot vary between them. Note this caches false as well as true, so it checks for the key
# rather than using ||=, since github.com correctly answers false here.
Contract C::None => C::Bool
def enterprise?
instance_signature = addr || ""
cache = Entitlements.cache[:github_enterprise]
return cache[instance_signature] if cache.key?(instance_signature)

meta = Retryable.with_context(:default) do
octokit.github_meta
end

meta.key? :installed_version
cache[instance_signature] = meta.key?(:installed_version)
end

# Read the members of an organization who are in a "pending" role. These users should
Expand Down
22 changes: 22 additions & 0 deletions spec/unit/entitlements/service/github_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,28 @@
})
expect(subject.enterprise?).to eq(true)
end

it "queries the API only once per instance across multiple organizations" do
stub = stub_request(:get, "https://github.fake/api/v3/meta").
to_return({
body: JSON.dump({ verifiable_password_authentication: true }),
headers: {
content_type: "application/json; charset=utf-8"
}
})

other_org = described_class.new(
addr: "https://github.fake/api/v3",
org: "puppiesinc",
token: "GoPackGo",
ou: "ou=puppiesinc,ou=GitHub,dc=github,dc=fake",
ignore_not_found: false
)

expect(subject.enterprise?).to eq(false)
expect(other_org.enterprise?).to eq(false)
expect(stub).to have_been_requested.once
end
end

describe "#pending_members" do
Expand Down
Loading