utils/github: refactor and update logic.
- better handle `HOMEBREW_GITHUB_API_USERNAME` and `HOMEBREW_GITHUB_API_PASSWORD` from `brew gist-logs` - only user personal access tokens from the macOS keychain (fixes #6862) - general refactoring and cleanup around the above
This commit is contained in:
parent
f1de689385
commit
8ad50cd4dc
@ -79,45 +79,57 @@ module GitHub
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def api_credentials
|
def env_token
|
||||||
@api_credentials ||= begin
|
ENV["HOMEBREW_GITHUB_API_TOKEN"].presence
|
||||||
if ENV["HOMEBREW_GITHUB_API_TOKEN"]
|
|
||||||
ENV["HOMEBREW_GITHUB_API_TOKEN"]
|
|
||||||
elsif ENV["HOMEBREW_GITHUB_API_USERNAME"] && ENV["HOMEBREW_GITHUB_API_PASSWORD"]
|
|
||||||
[ENV["HOMEBREW_GITHUB_API_PASSWORD"], ENV["HOMEBREW_GITHUB_API_USERNAME"]]
|
|
||||||
else
|
|
||||||
github_credentials = api_credentials_from_keychain
|
|
||||||
github_username = github_credentials[/username=(.+)/, 1]
|
|
||||||
github_password = github_credentials[/password=(.+)/, 1]
|
|
||||||
if github_username && github_password
|
|
||||||
[github_password, github_username]
|
|
||||||
else
|
|
||||||
[]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def api_credentials_from_keychain
|
def env_username_password
|
||||||
Utils.popen(["git", "credential-osxkeychain", "get"], "w+") do |pipe|
|
return if ENV["HOMEBREW_GITHUB_API_USERNAME"].blank?
|
||||||
|
return if ENV["HOMEBREW_GITHUB_API_PASSWORD"].blank?
|
||||||
|
|
||||||
|
[ENV["HOMEBREW_GITHUB_API_PASSWORD"], ENV["HOMEBREW_GITHUB_API_USERNAME"]]
|
||||||
|
end
|
||||||
|
|
||||||
|
def keychain_username_password
|
||||||
|
github_credentials = Utils.popen(["git", "credential-osxkeychain", "get"], "w+") do |pipe|
|
||||||
pipe.write "protocol=https\nhost=github.com\n"
|
pipe.write "protocol=https\nhost=github.com\n"
|
||||||
pipe.close_write
|
pipe.close_write
|
||||||
pipe.read
|
pipe.read
|
||||||
end
|
end
|
||||||
|
github_username = github_credentials[/username=(.+)/, 1]
|
||||||
|
github_password = github_credentials[/password=(.+)/, 1]
|
||||||
|
return unless github_username
|
||||||
|
|
||||||
|
# Don't use passwords from the keychain unless they look like
|
||||||
|
# GitHub Personal Access Tokens:
|
||||||
|
# https://github.com/Homebrew/brew/issues/6862#issuecomment-572610344
|
||||||
|
return unless /^[a-f0-9]{40}$/i.match?(github_password)
|
||||||
|
|
||||||
|
[github_password, github_username]
|
||||||
rescue Errno::EPIPE
|
rescue Errno::EPIPE
|
||||||
# The above invocation via `Utils.popen` can fail, causing the pipe to be
|
# The above invocation via `Utils.popen` can fail, causing the pipe to be
|
||||||
# prematurely closed (before we can write to it) and thus resulting in a
|
# prematurely closed (before we can write to it) and thus resulting in a
|
||||||
# broken pipe error. The root cause is usually a missing or malfunctioning
|
# broken pipe error. The root cause is usually a missing or malfunctioning
|
||||||
# `git-credential-osxkeychain` helper.
|
# `git-credential-osxkeychain` helper.
|
||||||
""
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def api_credentials
|
||||||
|
@api_credentials ||= begin
|
||||||
|
env_token || env_username_password || keychain_username_password
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def api_credentials_type
|
def api_credentials_type
|
||||||
token, username = api_credentials
|
if env_token
|
||||||
return :none if !token || token.empty?
|
:env_token
|
||||||
return :environment if !username || username.empty?
|
elsif env_username_password
|
||||||
|
:env_username_password
|
||||||
:keychain
|
elsif keychain_username_password
|
||||||
|
:keychain_username_password
|
||||||
|
else
|
||||||
|
:none
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def api_credentials_error_message(response_headers, needed_scopes)
|
def api_credentials_error_message(response_headers, needed_scopes)
|
||||||
@ -135,7 +147,7 @@ module GitHub
|
|||||||
credentials_scopes = "none" if credentials_scopes.blank?
|
credentials_scopes = "none" if credentials_scopes.blank?
|
||||||
|
|
||||||
case GitHub.api_credentials_type
|
case GitHub.api_credentials_type
|
||||||
when :keychain
|
when :keychain_username_password
|
||||||
onoe <<~EOS
|
onoe <<~EOS
|
||||||
Your macOS keychain GitHub credentials do not have sufficient scope!
|
Your macOS keychain GitHub credentials do not have sufficient scope!
|
||||||
Scopes they need: #{needed_human_scopes}
|
Scopes they need: #{needed_human_scopes}
|
||||||
@ -144,7 +156,7 @@ module GitHub
|
|||||||
#{ALL_SCOPES_URL}
|
#{ALL_SCOPES_URL}
|
||||||
#{Utils::Shell.set_variable_in_profile("HOMEBREW_GITHUB_API_TOKEN", "your_token_here")}
|
#{Utils::Shell.set_variable_in_profile("HOMEBREW_GITHUB_API_TOKEN", "your_token_here")}
|
||||||
EOS
|
EOS
|
||||||
when :environment
|
when :env_token
|
||||||
onoe <<~EOS
|
onoe <<~EOS
|
||||||
Your HOMEBREW_GITHUB_API_TOKEN does not have sufficient scope!
|
Your HOMEBREW_GITHUB_API_TOKEN does not have sufficient scope!
|
||||||
Scopes it needs: #{needed_human_scopes}
|
Scopes it needs: #{needed_human_scopes}
|
||||||
@ -168,9 +180,9 @@ module GitHub
|
|||||||
|
|
||||||
token, username = api_credentials
|
token, username = api_credentials
|
||||||
case api_credentials_type
|
case api_credentials_type
|
||||||
when :keychain
|
when :env_username_password, :keychain_username_password
|
||||||
args += ["--user", "#{username}:#{token}"]
|
args += ["--user", "#{username}:#{token}"]
|
||||||
when :environment
|
when :env_token
|
||||||
args += ["--header", "Authorization: token #{token}"]
|
args += ["--header", "Authorization: token #{token}"]
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -344,9 +356,9 @@ module GitHub
|
|||||||
_, reponame = repo.split("/")
|
_, reponame = repo.split("/")
|
||||||
|
|
||||||
case api_credentials_type
|
case api_credentials_type
|
||||||
when :keychain
|
when :env_username_password, :keychain_username_password
|
||||||
_, username = api_credentials
|
_, username = api_credentials
|
||||||
when :environment
|
when :env_token
|
||||||
username = open_api(url_to("user")) { |json| json["login"] }
|
username = open_api(url_to("user")) { |json| json["login"] }
|
||||||
end
|
end
|
||||||
json = open_api(url_to("repos", username, reponame))
|
json = open_api(url_to("repos", username, reponame))
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user