feat(github): add safeguards against accidental AllowInsecureHTTP use (#96) #113
@@ -96,8 +96,8 @@ type Client struct {
|
|||||||
// Higher-level exported methods (GetPullRequest, etc.) will use it to
|
// Higher-level exported methods (GetPullRequest, etc.) will use it to
|
||||||
// construct request URLs; remove this field if those methods end up
|
// construct request URLs; remove this field if those methods end up
|
||||||
// accepting full URLs instead.
|
// accepting full URLs instead.
|
||||||
baseURL string
|
baseURL string
|
||||||
token string
|
token string
|
||||||
httpClient *http.Client
|
httpClient *http.Client
|
||||||
|
|
||||||
// allowInsecureHTTP permits requests to HTTP (non-TLS) endpoints.
|
// allowInsecureHTTP permits requests to HTTP (non-TLS) endpoints.
|
||||||
@@ -155,23 +155,13 @@ type clientConfig struct {
|
|||||||
// environment variable. Without the env var set, the option is silently ignored
|
// environment variable. Without the env var set, the option is silently ignored
|
||||||
// and a warning is logged.
|
// and a warning is logged.
|
||||||
//
|
//
|
||||||
|
|
|||||||
// For tests, prefer AllowInsecureHTTPForTest which bypasses the env gate.
|
// For tests, use AllowInsecureHTTPForTest (defined in export_test.go) which bypasses the env gate.
|
||||||
func AllowInsecureHTTP() ClientOption {
|
func AllowInsecureHTTP() ClientOption {
|
||||||
return func(cfg *clientConfig) {
|
return func(cfg *clientConfig) {
|
||||||
|
gpt-review-bot
commented
[MINOR] AllowInsecureHTTPForTest is exported but intended only for tests. Consider making it unexported (allowInsecureHTTPForTest) and using it from package-internal tests, or clearly document and enforce via build tags/export_test.go if cross-package tests require it, to reduce risk of accidental production use. **[MINOR]** AllowInsecureHTTPForTest is exported but intended only for tests. Consider making it unexported (allowInsecureHTTPForTest) and using it from package-internal tests, or clearly document and enforce via build tags/export_test.go if cross-package tests require it, to reduce risk of accidental production use.
gpt-review-bot
commented
[NIT] For functional options, consider a With* naming convention (e.g., WithInsecureHTTP) to align with common Go patterns and improve discoverability (see configuration.md, Functional Options). **[NIT]** For functional options, consider a With* naming convention (e.g., WithInsecureHTTP) to align with common Go patterns and improve discoverability (see configuration.md, Functional Options).
|
|||||||
cfg.allowInsecureHTTP = true
|
cfg.allowInsecureHTTP = true
|
||||||
}
|
}
|
||||||
|
sonnet-review-bot
commented
[NIT] The doc comment for AllowInsecureHTTP() has an overly long line: 'For tests, use AllowInsecureHTTPForTest (defined in a _test.go file in the same package) which bypasses the env gate.' This wraps beyond 80 chars and doesn't follow the conventional line-length style seen elsewhere in the file, though this is cosmetic only. **[NIT]** The doc comment for AllowInsecureHTTP() has an overly long line: 'For tests, use AllowInsecureHTTPForTest (defined in a _test.go file in the same package) which bypasses the env gate.' This wraps beyond 80 chars and doesn't follow the conventional line-length style seen elsewhere in the file, though this is cosmetic only.
|
|||||||
}
|
}
|
||||||
|
sonnet-review-bot
commented
[MINOR] The doc comment for **[MINOR]** The doc comment for `AllowInsecureHTTP()` says the option is 'silently ignored' but the very next sentence says 'a warning is logged'. These are contradictory — being warned in logs is not silent. The comment should say something like 'the option is ignored and a warning is logged via slog.Warn'.
|
|||||||
|
|
||||||
// AllowInsecureHTTPForTest permits sending credentials over plaintext HTTP
|
|
||||||
// without requiring the REVIEW_BOT_ALLOW_INSECURE environment variable.
|
|
||||||
// This is intended exclusively for test code using httptest.Server.
|
|
||||||
func AllowInsecureHTTPForTest() ClientOption {
|
|
||||||
return func(cfg *clientConfig) {
|
|
||||||
cfg.allowInsecureHTTP = true
|
|
||||||
cfg.insecureIsTestBypass = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewClient creates a new GitHub API client.
|
// NewClient creates a new GitHub API client.
|
||||||
// If baseURL is empty, it defaults to https://api.github.com.
|
// If baseURL is empty, it defaults to https://api.github.com.
|
||||||
// For GitHub Enterprise, pass the API base URL (e.g. https://github.concur.com/api/v3).
|
// For GitHub Enterprise, pass the API base URL (e.g. https://github.concur.com/api/v3).
|
||||||
@@ -196,8 +186,8 @@ func NewClient(token, baseURL string, opts ...ClientOption) *Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &Client{
|
return &Client{
|
||||||
baseURL: strings.TrimRight(baseURL, "/"),
|
baseURL: strings.TrimRight(baseURL, "/"),
|
||||||
token: token,
|
token: token,
|
||||||
allowInsecureHTTP: cfg.allowInsecureHTTP,
|
allowInsecureHTTP: cfg.allowInsecureHTTP,
|
||||||
httpClient: &http.Client{
|
httpClient: &http.Client{
|
||||||
Timeout: 30 * time.Second,
|
Timeout: 30 * time.Second,
|
||||||
|
sonnet-review-bot
commented
[NIT] The warn log 'AllowInsecureHTTP ignored: set REVIEW_BOT_ALLOW_INSECURE=1 to enable' fires silently in tests that run in environments where the env var isn't set. Since NewClient is called in many tests (e.g. TestNewClient_DefaultBaseURL, TestParseRetryAfter_* etc.) without AllowInsecureHTTP(), this won't fire there. But any caller using AllowInsecureHTTP() in a test without the env var will produce a slog.Warn to whatever slog default is configured. The AllowInsecureHTTPForTest bypass prevents this for test servers, so this is acceptable — just worth noting that the warn will fire in non-test environments where someone misconfigures the option. **[NIT]** The warn log 'AllowInsecureHTTP ignored: set REVIEW_BOT_ALLOW_INSECURE=1 to enable' fires silently in tests that run in environments where the env var isn't set. Since NewClient is called in many tests (e.g. TestNewClient_DefaultBaseURL, TestParseRetryAfter_* etc.) without AllowInsecureHTTP(), this won't fire there. But any caller using AllowInsecureHTTP() in a test without the env var will produce a slog.Warn to whatever slog default is configured. The AllowInsecureHTTPForTest bypass prevents this for test servers, so this is acceptable — just worth noting that the warn will fire in non-test environments where someone misconfigures the option.
|
|||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package github
|
||||||
|
|
||||||
|
// AllowInsecureHTTPForTest permits sending credentials over plaintext HTTP
|
||||||
|
// without requiring the REVIEW_BOT_ALLOW_INSECURE environment variable.
|
||||||
|
// This is intended exclusively for test code using httptest.Server.
|
||||||
|
//
|
||||||
|
// Defined in a _test.go file so it is only available to test binaries.
|
||||||
|
func AllowInsecureHTTPForTest() ClientOption {
|
||||||
|
return func(cfg *clientConfig) {
|
||||||
|
cfg.allowInsecureHTTP = true
|
||||||
|
cfg.insecureIsTestBypass = true
|
||||||
|
}
|
||||||
|
}
|
||||||
[MINOR] AllowInsecureHTTPForTest is in the production file (client.go). Per the convention, test-only helpers should ideally live in an export_test.go file or be clearly gated. Since this function is exported and intended exclusively for test code, it bleeds test surface into the production API. Consider moving it to a file compiled only during tests (e.g., export_test.go), or renaming to make its test-only nature even more prominent in godoc.