Class UrlRedaction

java.lang.Object
io.github.intisy.gradle.github.utils.UrlRedaction

public final class UrlRedaction extends Object
Strips the parts of a URL that can carry a credential (userinfo, the query string) before it is used in a log line or an exception message.
Implementation Note:
A presigned or ?token=-style URL is the ordinary shape for a private Nexus, S3, or Artifactory download, and https://oauth2:TOKEN@host/repo.git is the ordinary shape for a private git clone URL; both carry a credential in a place this method removes. Locating that credential is done textually, not via URI: a credential that contains a / or + (the standard base64 alphabet an Azure DevOps PAT or similar token is drawn from), or a character URI rejects outright (a raw newline, a space, a brace, the ordinary shape of a token read via Groovy's file("token.txt").text), makes URI either throw or silently mis-parse the authority. So redact(java.lang.String) checks first, on the raw text, whether the shape between "://" and the last '@' looks like userinfo:secret@, and if so removes that whole span outright before ever asking URI to parse anything.

That check is scoped to end at the first ? or # after "://" (never at a /, since a leaked credential's own / must still be searched past). Without that bound, a credential-free URL whose query or fragment happens to contain a colon and a later @ (an ordinary shape: a mailto: link, a notify=admin@example.com parameter) would have its host and path destroyed by a match that was never really userinfo at all; RFC 3986 never allows a raw, unencoded ? or # inside userinfo, so bounding the search there loses no real coverage. Only a URL with no userinfo:secret@ span falls through to structured URI parsing (needed to preserve a port cleanly), and only a URL that URI still cannot parse falls through further to a best-effort manual strip.

  • Method Details

    • redact

      public static String redact(String url)
      Parameters:
      url - the URL to redact; may be null.
      Returns:
      url with any userinfo and query string removed, or null if url was null. A value this method cannot parse as a URI (for example, the git@host:owner/repo.git scp-like syntax, or a URI-illegal character inside userinfo) has its userinfo and query string stripped on a best-effort textual basis instead.