Loading
Commits on Source 6
-
Matt Cockayne authored
forge.WithHTTPTransport and forge.WithHTTPClient record what they are given and no first-party adapter reads it back. Every adapter's factory takes opts ...forge.Option and consults exactly one thing, Options.Logger, before calling NewReleaseProvider — and no adapter's Settings has a field for the value to reach. The documentation said otherwise. The configuration reference listed both rungs as working options, the authoring guide told provider authors what to do with them, and the reuse-a-connection guide opened with transport sharing as "the cheapest change, and the one to make first" over a copy-pasteable example. A consumer following that example gets no effect, no error, and no way to find out. That is worse than the rung not existing, and it is documentation rather than code that made it so — the audit recorded in spec 0008's revision log found the gap, and this closes the half that misleads. - godoc on both options and on the package block says NOT YET CONSUMED, and points at forge/pool, which reuses the whole provider and works today; - reuse-a-connection leads with the pool and demotes the transport rung to a section that says plainly it does nothing yet; - the configuration reference carries the same warning beside the table; - the authoring guide keeps the instruction — it is the contract a new provider should honour — and adds that none of the first-party four do, with the warning that a partial adoption is worse than none. forge-github builds a client in three places, one of them the asset download, so a provider honouring the injection on its API client alone would hand a caller a pool that quietly does not cover every request. Four stale claims found while reading, all predating this change and all now describing a codebase that no longer exists: - reuse-a-connection said the module "does not yet surface errors that assert credential-invalidity", so Invalidate could not be used from a provider's error. forge.ErrUnauthorized shipped in v0.13.0 and is exactly that signal. Replaced with the example, and with which two sentinels must NOT trigger it. - backend-agnosticism repeated the "ErrReleaseNotFound is not yet uniform" claim already corrected in the errors reference. It is uniform, and the conformance harness enforces it; what varies is which sentinel a bare 404 carries, which is a provider decision (0009 D4). - limitations and the providers reference both documented ReleaseSource.Private as a construction-time fast failure. The field went with ReleaseSourceConfig (0008 D3) and the check it fed moved to the operation (D8), because whether a repository is private is not knowable at construction. No code changes beyond doc comments. -
Matt Cockayne authored
Two of the three first-party SDKs offer a method that leaks a credential when used exactly as its name suggests. Both were verified by request against the versions this module pins, not by reading the source. go-gitlab v2.58.0. NewRequestToURL attaches PRIVATE-TOKEN to a request for any URL and refuses a URL off the client's base host, which reads as a guardrail. It is not one: the check runs when the request is BUILT, and the client then follows a redirect off-host carrying the credential. An instance asset link redirecting to object storage is GitLab's ordinary path for a large file, so the correct looking use of the SDK's own arbitrary-URL method sends the token wherever a release author's link resolves. go-github v90.0.0. Client() returns the underlying *http.Client, whose every request carries Authorization: Bearer <token> to any host. The only protection is its doc comment. Its download path is correct by contrast, and is documented here as the shape to copy: bareDoUntilFound stops at the redirect, then refetches with a fresh credential-free request through a caller-supplied client. gitea.dev/sdk v1.2.0 exposes no client accessor, no token accessor and no arbitrary-URL request method, so there is nothing to misuse. The reason this is documentation rather than a code change is that forge is already safe: forge-gitlab builds its download client with httpclient.WithSensitiveHeaders("PRIVATE-TOKEN"), whose CheckRedirect deletes the header on any cross-host hop, and TestDownloadReleaseAsset_TokenNotForwardedAcrossRedirect pins it. What was missing was any record of WHY that is load-bearing — so the next person to reach for the SDK's tidier-looking path knows what it costs. Recorded in spec 0008's D5 revision as the finding that settled the rung, and rejected there as a simplification: routing forge-gitlab's download through NewRequestToURL would have been a security regression. -
Matt Cockayne authored
Spec 0008 D4 and D5 are built. The documentation said the transport rungs were recorded and read by nothing, which was true when it was written and is not now: all four adapters honour both options for their own API requests, and forge-github, forge-gitlab and forge-gitea offer NewProviderFromClient. What replaces the warning is the part a caller still needs to know, because it is a deliberate limit rather than a gap: no adapter uses a supplied CLIENT to fetch a release asset. That URL comes from author-controlled metadata, and whether a credential can leave the pinned host is decided by the fetching client's redirect behaviour. A supplied client carries the caller's policy, and may carry the caller's credentials in headers the standard library does not know to strip — it protects Authorization, Cookie and WWW-Authenticate on a cross-host redirect and nothing else. An adapter cannot inspect a client to find out, so it builds its own for that hop. A supplied transport is used everywhere, so the pooling benefit is complete either way. reuse-a-connection gains a section for rung 1, including the consequence that differs by forge: downloads stay authenticated on GitHub, because go-github's download rides the SDK client and follows the redirect credential-free, and go anonymous on GitLab and Gitea, where an asset is an author-supplied URL the SDK never fetches and neither SDK exposes its credential. A private asset therefore resolves on one and fails on the other two, which is a property of the rung rather than a defect, and the escape is a lower rung. direct gains the documented absence D5 requires: it has no platform SDK, so its native unit is the *http.Client and a rung taking one would duplicate WithHTTPClient.
-
Matt Cockayne authored
A documentation audit against the source, run because six drift findings had already surfaced by accident during two specs' implementation. It found eleven more, plus a stale index; sweeping for the same shapes afterwards found three the audit missed. Snippets that do not compile, which is the worst of it because a reader copies them: - README.md and two snippets in migrate-from-resolvetoken referenced `src` inside a closure whose parameter is `ep forge.Endpoint` — the name of the type the Endpoint cut replaced, so they read as the old API throughout. - author-a-provider built a Settings literal with a ReleaseSource field that does not exist; the field is Endpoint. - logging.md carried the same `src` in two more factory calls. migrate-from-resolvetoken additionally taught the anti-pattern its own next section forbids: it passed forge.SubConfig(cfg, "github") into SettingsFromConfig, four lines above the paragraph explaining that doing so makes the adapter look for github.github.auth.value and quietly find nothing. That function's own doc comment calls it "the second-most-common mistake". Claims that were true when written and are not now: - limitations said ErrReleaseNotFound is not uniform and not to be relied on. It is uniform, and the conformance harness enforces it. What varies is which not-found sentinel a bare 404 carries, which is a provider decision. - configuration documented ReleaseSourceConfig.Private as a bitbucket construction-time fast failure. The field went with the type in 0008 D3, and the check moved to the operation in D8. - getting-started said WithLogger is the only option. There are three. - providers referenced ReleaseSource.Host in four places and pinned go-github/v89; the module is on v90. - direct-provider documented the {tool} default as ReleaseSource.Repo; it is the literal string "tool". - testing listed eleven mocks; there are twelve, and MockSnippets was missing from the table. - conformance-harness said sixteen checks against a seventeen-row table. The count was wrong before this cycle and my own edit adding two checks carried the error forward rather than fixing it. The specs index gains 0009, which shipped code has been citing since v0.14.0. Docs only; no behaviour change. -
Matt Cockayne authored
-
Matt Cockayne authored