)]}'
{
  "log": [
    {
      "commit": "e3555596568496855f0c0c055a54e127854706b3",
      "tree": "67c6f2a0313be503822d92aa98d73265db2e223f",
      "parents": [
        "75d4e1639e6a096f51ad733ea4e927cbf0367843"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Oct 11 09:40:44 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Oct 11 09:54:42 2026 +0200"
      },
      "message": "Bazel: Remove Maven-era directory structure\n\nMigrate source and resource trees from the legacy Maven layout\n(src/main/java, src/main/resources) to standard Bazel top-level\ndirectories (java, resources).\n\nUpdate BUILD.bazel targets, package label dependencies, resource\nglobs, and sub-package BUILD.bazel files across provider modules\nto reflect the new paths.\n\nChange-Id: I4d6881a6ab867cc8252ab75e29e49ec37df396b2\n"
    },
    {
      "commit": "75d4e1639e6a096f51ad733ea4e927cbf0367843",
      "tree": "f2296907631a568d05912cabac7ce6153066dc99",
      "parents": [
        "457276c0e952c0091f31237037eb1aa2ba276b89"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Oct 11 09:29:55 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Oct 11 09:54:41 2026 +0200"
      },
      "message": "Remove .bazelversion\n\nStandalone build mode was removed in I036cdaf095, but this file was\nleft behind.\n\nChange-Id: Ie1fd48ce5fc7d24416dc9fbe84ac4427acc5aba2\n"
    },
    {
      "commit": "457276c0e952c0091f31237037eb1aa2ba276b89",
      "tree": "5249ff6bd0eee0080ef028fab9519465e9b7ae26",
      "parents": [
        "36cff8d52f25ee2fa2ca083d4f0c245410af41ad"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Oct 11 09:23:25 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Oct 11 09:54:41 2026 +0200"
      },
      "message": "Bump nimbusds version to 10.10\n\nAlso update rules_jvm_external to 7.1.\n\nChange-Id: I94d9d395e657d549ed5e889c1fc6b517aad60485\n"
    },
    {
      "commit": "36cff8d52f25ee2fa2ca083d4f0c245410af41ad",
      "tree": "5549fa5cf2db4cc370b6a75f05c9c996c110183a",
      "parents": [
        "c8accf8c85ee091c1473baf6d380fce9338e8b3f"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sat Oct 10 23:14:09 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sat Oct 10 15:01:13 2026 -0700"
      },
      "message": "Use core SecureRandomUtil for the PKCE code_verifier\n\nCore added com.google.gerrit.util.crypto.SecureRandomUtil as the single\nsource of cryptographically strong randomness and migrated its callers\nto it. Migrate the plugin\u0027s only SecureRandom use, the PKCE\ncode_verifier in HttpOAuthClient, to it.\n\nSecureRandomUtil.newRandomString32() returns 32 bytes of entropy as\nunpadded base64url, which is identical to the previous SecureRandom\nplus base64url encoding and a valid RFC 7636 code_verifier, so there is\nno behaviour change.\n\nChange-Id: Id7909f834f793ee720e9dac26808699e3c1368ef\n"
    },
    {
      "commit": "c8accf8c85ee091c1473baf6d380fce9338e8b3f",
      "tree": "155af5e40aa5d2166ec8b85c1503b09f6cdea3a8",
      "parents": [
        "4a323f734685e6c26aa9b2514c8afa30ef1be21d"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sat Oct 10 15:27:16 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sat Oct 10 15:34:18 2026 +0200"
      },
      "message": "Use java.net.HttpURLConnection constants for status code checks\n\nThese classes compare the status of outbound HTTP client responses\nOAuthHttpTransport.Response.code is HttpURLConnection.getResponseCode()\nnot servlet responses, so replace the HttpServletResponse.SC_* constants\nwith the equivalent java.net.HttpURLConnection.HTTP_* constants.\n\nThis de-leaks the javax.servlet namespace from these files in favour of\nthe JDK-native java.net alternative, in preparation for the migration to\nthe jakarta namespace.\n\nNo behaviour change because the integer values are identical.\n\nChange-Id: I463ae844ee2444d6802ccfc69eca52bb00000000\n"
    },
    {
      "commit": "4a323f734685e6c26aa9b2514c8afa30ef1be21d",
      "tree": "45c3065663c427f4cb1edf0d96e97555028b2504",
      "parents": [
        "4eca6b90f68f50e7ccae2ad447f145ae852411d1"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Thu Oct 08 13:14:07 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Thu Oct 08 13:36:07 2026 +0200"
      },
      "message": "Support link-to-existing-gerrit-accounts for Keycloak\n\nThe SAP IAS and Discovery providers already honor\nlink-to-existing-gerrit-accounts: when set, a first browser login\nlinks to an existing Gerrit account by username instead of always\ncreating a new one. Add the same option to Keycloak, reusing that\nmechanism rather than inventing a new one.\n\nKeycloakUserInfoMapper gains the same map()/mapForBrowser() split as\nDiscoveryUserInfoMapper. map() (the Git-over-HTTP path) keeps a null\nclaimed identity. mapForBrowser(), when the flag is set, emits a\ngerrit:\u003cpreferred_username\u003e claimed identity, and fails closed if the\nflag is set but no preferred_username is present, so linking is never\nsilently skipped. Claimed identity is only read by the browser\nOAuthSession, so the Git path is unaffected by the flag.\n\nKeycloakOAuthService reads LINK_TO_EXISTING_GERRIT_ACCOUNT and maps\nbrowser claims via mapForBrowser(). KeycloakTokenValidator keeps mapping\nvia map(), so Git-over-HTTP continues to authenticate by external id\nonly. KeycloakInitStep prompts for the option like the Discovery init\nstep.\n\nFeature: https://github.com/davido/gerrit-oauth-provider/issues/181\nChange-Id: I19d01a6964be8c5432bd20bea0f061b07114d401\n"
    },
    {
      "commit": "4eca6b90f68f50e7ccae2ad447f145ae852411d1",
      "tree": "f5bb82fb211c984161225700760e75d142e17cad",
      "parents": [
        "3d597274e932df7e392e6daa8a42af6d91be85a3"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Oct 06 17:41:26 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Oct 06 17:52:31 2026 +0200"
      },
      "message": "init: default PKCE to enabled\n\nFlip each provider init step\u0027s enable-pkce prompt default to true, and\nthe config.md examples to match. The runtime default is unchanged, so\nexisting configs are unaffected.\n\nChange-Id: I007d3f9cb85cb37a8d7ebdf18ff984a59fd04641\n"
    },
    {
      "commit": "3d597274e932df7e392e6daa8a42af6d91be85a3",
      "tree": "6eb7eb8f4ff073ecdc41aed2ac9a37331efbe52f",
      "parents": [
        "7e9ee35eac61ee450f21ba1df680a6f1884bb915"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Oct 06 17:16:25 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Oct 06 17:19:22 2026 +0200"
      },
      "message": "init: delegate to providers\u0027 own init steps\n\nThe global init step inlined them instead of delegating.\n\nChange-Id: I4ba57ff9cfb1aa20095791c6cea52718a2e54c9b\n"
    },
    {
      "commit": "7e9ee35eac61ee450f21ba1df680a6f1884bb915",
      "tree": "ba9085e95839f5ad4513864d2a9ea4b05d1f0082",
      "parents": [
        "85d2c71393970e7268247a3fb5f4da52f336e956"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Oct 06 12:02:59 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Oct 06 16:49:04 2026 +0200"
      },
      "message": "Split the plugin BUILD into per-package BUILD.bazel files\n\nEach core library and provider now has its own BUILD.bazel next to its\nsources, holding its library, single-provider artifact, and tests,\ninstead of one root file that listed everything.\n\nA provider.bzl macro covers the uniform providers and their tests; SAP\nIAS keeps its own file for its SAP deps. Internal libraries use bazlets\u0027\ngerrit_plugin_library(), so ext_deps are Maven coordinates and\nPLUGIN_DEPS_NEVERLINK and the @oauth_plugin_deps labels are gone. The\ncore java_library aggregate becomes a CORE list in provider.bzl.\n\nThe root BUILD.bazel now only assembles the default oauth.jar; the\noauth-\u003cprovider\u003e artifacts live in their own packages and the old root\naliases are dropped. The built artifacts are unchanged and the guardrail\ntests still pass.\n\nChange-Id: I6e82a94c12088ebcb6d5565fd88a2fa3cfddf66e\n"
    },
    {
      "commit": "85d2c71393970e7268247a3fb5f4da52f336e956",
      "tree": "49c5829c0a950b9ab7f4a10cd174c26b84c7d204",
      "parents": [
        "8001439bf83803320f30879065c56d08614b477f"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Oct 06 11:38:43 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Oct 06 13:00:14 2026 +0200"
      },
      "message": "Drop the standalone plugin build mode\n\nThe plugin supported two Bazel build modes: standalone (building the\nplugin repository as its own root module) and in the Gerrit source\ntree. The standalone mode added a parallel scaffold that was awkward to\nkeep working and in sync with the in-tree build.\n\nKeep only the in-tree build. MODULE.bazel and\nexternal_plugin_deps.MODULE.bazel still contribute the plugin\u0027s\nthird-party runtime dependencies (oauth_plugin_deps) to Gerrit\u0027s root\nmodule, but MODULE.bazel is trimmed to just that. Its bazlets\ndependency and the gerrit-plugin-api / acceptance-framework fetch\n(gerrit_api_version, external_plugin_deps) only served the standalone\nbuild.\n\nRewrite the build documentation for the in-tree build only, and fix\nthe dependency guardrail test target names.\n\nThis also unblocks a follow-up that splits the monolithic BUILD into\nper-provider BUILD.bazel files, which is substantially simpler with a\nsingle build mode.\n\nChange-Id: I036cdaf0951d97a26182898da1a967375b6a4042\n"
    },
    {
      "commit": "8001439bf83803320f30879065c56d08614b477f",
      "tree": "244c450c8a71b120fc0cbf551e1071eceed182e0",
      "parents": [
        "806087d512ab1670139404b2fde8ed3ff8d4cad8"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Oct 06 11:02:07 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Oct 06 11:07:21 2026 +0200"
      },
      "message": "Package the remaining OAuth providers as standalone artifacts\n\nThe AirVantage, Azure, Bitbucket, CAS, Dex, Facebook, GitLab, and\nPhabricator providers were the last ones bundled only in the default\noauth.jar, without a standalone artifact. Give each its own\ngerrit_plugin_library plus a PluginModule and InitStep, and emit a\nsingle-provider oauth-\u003cname\u003e.jar, matching the Discovery, GitHub,\nGoogle, Keycloak, and SAP IAS providers that were split earlier.\n\nThe default oauth.jar continues to bundle the same set of providers,\nnow assembled from the individual provider libraries instead of the\ncatch-all providers library, which is removed. SAP IAS stays\nstandalone-only, as before.\n\nChange-Id: Ifedf9dd6c6b8fcd13fccb8a2abb6c698de9cf333\n"
    },
    {
      "commit": "806087d512ab1670139404b2fde8ed3ff8d4cad8",
      "tree": "2a83531ada179d1a1c659c8d56fd5cda5eeb673d",
      "parents": [
        "5d4a02d063e223d3cf3b34d50cd2b7bd3576b506"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Oct 06 09:53:08 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Oct 06 10:22:30 2026 +0200"
      },
      "message": "Package SAP IAS as a standalone OAuth artifact\n\nMove SAP IAS out of the all-inclusive oauth.jar and package it as\noauth-sapias.jar. Add standalone module and init-step wiring for the SAP\nIAS artifact, and keep the SAP Cloud Security dependencies scoped to\nthat artifact.\n\nDeployments that need SAP IAS should install oauth-sapias.jar. The\ncommon oauth.jar no longer contains SAP IAS provider classes or the SAP\nruntime dependency stack (env, java-api, java-security, token-client,\nand related service-binding jars), as enforced by the runtime dependency\nallowlist.\n\nAdd a dedicated sapias_tests target so SAP IAS coverage remains explicit\nafter removing it from the common provider test set.\n\nChange-Id: I0875cd9394fadb1e115ee23a349be69f0db5d101\n"
    },
    {
      "commit": "5d4a02d063e223d3cf3b34d50cd2b7bd3576b506",
      "tree": "7c274b4b1166b78b55f177607104229eeda5bd9b",
      "parents": [
        "c31a4db28e62b378e80dc0a5d3e97a7c6f7999c2"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Oct 06 09:53:07 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Oct 06 10:10:14 2026 +0200"
      },
      "message": "Rename SAP IAS OAuth package to sapias\n\nRename the SAP IAS provider package from sap to sapias so it matches\nthe provider name and standalone artifact naming.\n\nRelease-Notes: skip\nChange-Id: I3ab32b4f2fe0a8fb5d3ef807d594889ade1fefd3\n"
    },
    {
      "commit": "c31a4db28e62b378e80dc0a5d3e97a7c6f7999c2",
      "tree": "ec12c7ce42d5c9c5ef34957daab1ca0f487678eb",
      "parents": [
        "e31e4d055a463b1e92e5453471fe13b6d054b08b"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Sep 22 12:33:14 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Sep 22 14:43:28 2026 +0200"
      },
      "message": "Allow building standalone single-provider plugin artifacts\n\nAdd per-provider libraries and standalone oauth-google, oauth-github,\noauth-discovery, and oauth-keycloak targets. Each bundles the shared\ncore (base, client, jwt, utils) plus one provider, wired by that\nprovider\u0027s PluginModule and InitStep, and registers as the same\ngerrit-oauth-provider plugin, so gerrit.config and init behave exactly\nas with the full oauth.jar.\n\nThe targets are optional and do not affect the default oauth build,\nwhose provider coverage is unchanged.\n\nDocument the feature in build.md and README.\n\nChange-Id: I51e936e25163807e164ea86893b7144e86dc9fe4\n"
    },
    {
      "commit": "e31e4d055a463b1e92e5453471fe13b6d054b08b",
      "tree": "d5d71b5907a1970bd0609590689aa75fa3633f0a",
      "parents": [
        "0cdd76fb81939f57eef063c8ae070ca9b237f7bb"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Sep 22 12:32:46 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Sep 22 14:43:28 2026 +0200"
      },
      "message": "Decouple OAuth providers from the plugin\u0027s core wiring\n\nExtract the provider-agnostic Guice and init wiring into\nAbstractOAuthModule and AbstractOAuthInitStep, so an artifact declares\nonly the providers it bundles. Move the shared SupportedLoginProvider,\nOAuthExternalIdCreator, and DisabledOAuthLoginProvider into the base\npackage.\n\nGive each provider a small PluginModule and InitStep that wire just\nitself. The all-inclusive Module and InitOAuth continue to bundle every\nprovider; InitOAuth delegates the providers that also ship standalone to\ntheir own init steps and keeps the rest inline. Behavior of the oauth\nplugin is unchanged.\n\nThis prepares the ground for building single-provider artifacts.\n\nChange-Id: I7d0676df6b8d31ee08b04bda77b378ec67d0667a\n"
    },
    {
      "commit": "0cdd76fb81939f57eef063c8ae070ca9b237f7bb",
      "tree": "8df9a1d53510c0b47a8e5a573e69b1a0373ffc8b",
      "parents": [
        "844d8fbe0d6cbb9f2ef1105fd7ae66222a8add0a"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 13 18:49:12 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Sep 22 11:25:03 2026 +0200"
      },
      "message": "Add OAuth token revocation support\n\nAdd RFC 7009 revocation to the native HTTP client and wire Google and\nKeycloak to their provider revocation endpoints.\n\nFlush cached Git-over-HTTP validations when core revokes a token, using\ntargeted invalidation when possible and a full flush when the account\ncannot be mapped safely.\n\nDepends-On: https://gerrit-review.googlesource.com/c/gerrit/+/630424\nChange-Id: I74514da03cd5a75e26ec7549c1f0a9ebec9c032d\n"
    },
    {
      "commit": "844d8fbe0d6cbb9f2ef1105fd7ae66222a8add0a",
      "tree": "664d5cd27d4b54f6cf418ad3bfb0f75a02be3080",
      "parents": [
        "417712fcdc5a8e3066717ea17ec42edcc328ceb4"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 05:02:59 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Sep 22 11:25:03 2026 +0200"
      },
      "message": "Add OAuth access-token refresh support\n\nTeach refresh-capable providers to request and preserve refresh tokens,\nstamp issued tokens with provider ids, and refresh expired access tokens\nthrough the native HTTP client. Add provider configuration docs\n(discovery, Keycloak, GitLab) and refresh the config overview.\n\nThis intentionally leaves the oauth-token SSH command and token\nencryption in Gerrit core.\n\nChange-Id: I16c64bce8041b9fe2cb998ed7e63dd70045c1f27\n"
    },
    {
      "commit": "417712fcdc5a8e3066717ea17ec42edcc328ceb4",
      "tree": "6a60b42657a7ed4f9fc58251301788bef64b0413",
      "parents": [
        "2eaef9d7d9f8dc46a9cec180650e3e97aac895d1"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 13 18:48:22 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Sep 22 11:25:03 2026 +0200"
      },
      "message": "Contribute OAuth providers in the sys injector\n\nRegister configured OAuthServiceProvider implementations from the plugin\nsys module so Gerrit core can resolve the issuing provider for browser\nlogin, token refresh, and the core oauth-token command.\n\nDrop the obsolete plugin HTTP module entry point.\n\nChange-Id: I9d74c6606b9422f04a7e81c5049ab92df3df4e87\n"
    },
    {
      "commit": "2eaef9d7d9f8dc46a9cec180650e3e97aac895d1",
      "tree": "9aaea050164963cdb2c33d1ff676d20d4d258156",
      "parents": [
        "6232ce04e5517472288a3a9ec6846685edbe04bf"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 13 18:45:22 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Sep 22 11:25:03 2026 +0200"
      },
      "message": "Remove ScribeJava and deprecated wrappers\n\nDrop the soft-deprecated wrapper providers and remove the ScribeJava and\nJackson runtime dependencies from the plugin.\n\nThe remaining providers use the native HTTP OAuth client.\n\nChange-Id: I437e49b112c7112f5c81b93341daf94c55a04835\n"
    },
    {
      "commit": "6232ce04e5517472288a3a9ec6846685edbe04bf",
      "tree": "b1d4668fbef6ccfb1e25df0015b1379278d736c2",
      "parents": [
        "32a280d3af3a34449258b9f60b6b522eecaa45ef"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 04:30:37 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Sep 22 11:23:21 2026 +0200"
      },
      "message": "Document GitHub and Google provider configuration\n\nAdd configuration guides for the GitHub and Google providers, including\nGit-over-HTTP setup.\n\nChange-Id: Ifd5e9bdd5eda389d65a26aaff05b2174a3150bf2\n"
    },
    {
      "commit": "32a280d3af3a34449258b9f60b6b522eecaa45ef",
      "tree": "e6c90be8385d5cb685e5b03d127c039c54d99f94",
      "parents": [
        "7bd22e8de13ef544f784a2eac56927524f1233b2"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 04:30:37 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Sep 22 11:23:21 2026 +0200"
      },
      "message": "Add git-credential helper for Git-over-HTTP\n\nAdd a contrib git-credential-google-gerrit helper (and README) that\nobtains and caches an OAuth access token for Git-over-HTTP against\nGerrit, for providers that support it.\n\nChange-Id: I7b0bce48e218ccf8476c739e04c9a97e636b45b2\n"
    },
    {
      "commit": "7bd22e8de13ef544f784a2eac56927524f1233b2",
      "tree": "2c54a87130a7cfefd7a0856bde128d86161dac70",
      "parents": [
        "0a90dd0921f98b48350e8672f35cdad08362d7e5"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 04:30:37 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Sep 22 11:21:32 2026 +0200"
      },
      "message": "Modularize the plugin build into libraries\n\nSplit the monolithic plugin target into utils, client, base, jwt and\nproviders-native libraries with explicit dependencies, so the layers\nbuild and test independently. No source changes.\n\nChange-Id: I2a02e449ac3ef7680a0e4bd677a0a127e1b37a2f\n"
    },
    {
      "commit": "0a90dd0921f98b48350e8672f35cdad08362d7e5",
      "tree": "b0ad28dab1ffa24206232af078d95e81472ab387",
      "parents": [
        "60071d7d7935d1f4a3417887aeefed3d31f626b8"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 04:29:45 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Sep 22 11:01:48 2026 +0200"
      },
      "message": "Drop legacy config-key constants from InitOAuth\n\nAll providers now read configuration through OAuthConfigKeys, so remove\nthe duplicated key constants from InitOAuth and update its init prompts\nfor the native client.\n\nChange-Id: I1a5d6b56241e541f42af121c1271a6b7f57f9adb\n"
    },
    {
      "commit": "60071d7d7935d1f4a3417887aeefed3d31f626b8",
      "tree": "7f9ce9fa9b9dd543ed2b60d431d5371250f15b22",
      "parents": [
        "b3fcf9ba60a50428602fefe61e0f0c094b38a906"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 05:02:22 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Sep 22 11:01:48 2026 +0200"
      },
      "message": "Add Git-over-HTTP support for Azure AD\n\nAdd Azure AD\u0027s Git-over-HTTP token validator and login provider and\nregister Azure in the provider list. Add ModuleTest covering selection of\nthe single git-over-http provider and the multiple-provider guard.\n\nChange-Id: If9ecd878e4f86975cf93d36b5306b78a5fe21fcd\n"
    },
    {
      "commit": "b3fcf9ba60a50428602fefe61e0f0c094b38a906",
      "tree": "69278c6631972c763b4bd08ea38ffee6a45cfce4",
      "parents": [
        "a45bd430e7d03a2994d3382783b0ebd03f6545a6"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 05:01:34 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Sep 22 11:01:48 2026 +0200"
      },
      "message": "Add Git-over-HTTP support for GitLab\n\nAdd GitLab\u0027s Git-over-HTTP token-info validator and login provider and\nregister GitLab in the provider list, selectable via enable-git-over-http.\n\nChange-Id: I594a91bb7d8fd3eb34a2bbb7d17e939273c60833\n"
    },
    {
      "commit": "a45bd430e7d03a2994d3382783b0ebd03f6545a6",
      "tree": "e0c44f09f508f9ba448e8037abfbcfc58362c311",
      "parents": [
        "60c7f864ec28f1370c46219b2949d748b8e0277a"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 05:00:43 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Sep 22 11:01:48 2026 +0200"
      },
      "message": "Add Git-over-HTTP support for GitHub\n\nAdd GitHub\u0027s Git-over-HTTP check-token validator and login provider and\nregister GitHub in the provider list, selectable via enable-git-over-http.\n\nChange-Id: Ie178868034335c45becc38d6601c35c9a6df5123\n"
    },
    {
      "commit": "60c7f864ec28f1370c46219b2949d748b8e0277a",
      "tree": "84bd05aac39f94e827b6c8106f2089b869f681c7",
      "parents": [
        "203f77d3cd8212f3555b5fb6a9d0e48701e4caad"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 04:59:53 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Sep 22 11:01:48 2026 +0200"
      },
      "message": "Add Git-over-HTTP support for Google\n\nAdd Google\u0027s Git-over-HTTP token-info validator and login provider and\nregister Google in the provider list, selectable via enable-git-over-http.\n\nChange-Id: I5bbf14cf3816fcb58c5d6c12af834d31a1343f4d\n"
    },
    {
      "commit": "203f77d3cd8212f3555b5fb6a9d0e48701e4caad",
      "tree": "721bae02da807b4dbbf197f70b5e1686d31fc3da",
      "parents": [
        "384e35686b918eb68dd86083c0c004894441d376"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 04:59:05 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Sep 22 11:01:48 2026 +0200"
      },
      "message": "Add Git-over-HTTP support for the discovery provider\n\nAdd the discovery provider\u0027s Git-over-HTTP token validator and login\nprovider and register it in the provider list, selectable via\nenable-git-over-http.\n\nChange-Id: I079cc4f3cd0b9b588f8422172066e2404eb496e6\n"
    },
    {
      "commit": "384e35686b918eb68dd86083c0c004894441d376",
      "tree": "a72339f31f1d510f739ce00358c66d0a7b5b935f",
      "parents": [
        "d47dd3d07be31ecde5a5f02c55e48ee3a9c426e5"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 04:57:05 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Sep 22 11:01:48 2026 +0200"
      },
      "message": "Add Git-over-HTTP support for Keycloak\n\nAdd Keycloak\u0027s Git-over-HTTP token validator and login provider and\nregister Keycloak in the provider list so it can be selected via\nenable-git-over-http.\n\nChange-Id: If2e1b0a24b7d6ccfe577fc7f9d7f6b9d9aab2292\n"
    },
    {
      "commit": "d47dd3d07be31ecde5a5f02c55e48ee3a9c426e5",
      "tree": "038b7de921e170f3c9c6c9674c410c7d8cf34b50",
      "parents": [
        "2bd001a8e1cec3ae2c11b78c82e1147fb197ae0d"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 04:24:57 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Sep 22 11:01:48 2026 +0200"
      },
      "message": "Add Git-over-HTTP token-validation framework\n\nIntroduce a small framework for validating OAuth access tokens presented\nover Git-over-HTTP: an OAuthTokenValidator SPI, a shared\nOAuthTokenValidationCache, a GitOverHttpModule base that binds a\nprovider\u0027s validator and login provider, and an\nAbstractTokenValidatorLoginProvider base. Module now selects the single\nprovider with enable-git-over-http and installs its module, driven by a\nSupportedLoginProvider registry. SAP (grandfathered on) is the first\nregistered provider; others follow in their own changes.\n\nChange-Id: I3220170d84740109c77cecd8be686fbb90dfc85e\n"
    },
    {
      "commit": "2bd001a8e1cec3ae2c11b78c82e1147fb197ae0d",
      "tree": "38ccd4068cd2d964f27311140b97fc2096feabac",
      "parents": [
        "f189e045bd06770dd5dc6bcd01b2d5c860e24fb0"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 04:22:19 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Mon Sep 21 18:49:39 2026 +0200"
      },
      "message": "Adopt OAuthConfigKeys in service wiring and relocate JsonUtil test\n\nSwitch OAuthServiceModule to read the client-id via OAuthConfigKeys and\nmove JsonUtilTest alongside JsonUtil under utils. Allowlist the\nnimbus-jose-jwt runtime jar. Import-only cleanup in HttpModule.\n\nChange-Id: Ibc32891b84315f1c73101cc68da6e0cc885c9ab2\n"
    },
    {
      "commit": "f189e045bd06770dd5dc6bcd01b2d5c860e24fb0",
      "tree": "ea04976a2b287ad4b5791273505910f14aaa161e",
      "parents": [
        "22ee144252252470a8525c631b1e20b7e7e9af0b"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 04:18:36 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Mon Sep 21 18:49:39 2026 +0200"
      },
      "message": "Migrate SAP IAS to the native OAuth client\n\nChange-Id: I214e023aa6b34ed99845802dbc1913ede148ac48\n"
    },
    {
      "commit": "22ee144252252470a8525c631b1e20b7e7e9af0b",
      "tree": "209005790cb6e31b3a6d8dfa0b1c2de1e0f54462",
      "parents": [
        "8c06dc275027f8deb5d00e8ee21f2af04f88dee2"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 04:18:12 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Mon Sep 21 18:49:39 2026 +0200"
      },
      "message": "Migrate GitLab to the native OAuth client\n\nChange-Id: I0b5adf3449ff7ca5759d44def27616c1e879ee61\n"
    },
    {
      "commit": "8c06dc275027f8deb5d00e8ee21f2af04f88dee2",
      "tree": "b839c55ba2f527d15e1113dc99dd7116ac44407e",
      "parents": [
        "9c25b4449c5894ebb9ef52f85aba2417ef4c5b23"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 04:17:55 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Mon Sep 21 18:49:39 2026 +0200"
      },
      "message": "Migrate Keycloak to the native OAuth client\n\nChange-Id: Ia81e3e970b716656932da51310e30349f80e0dd8\n"
    },
    {
      "commit": "9c25b4449c5894ebb9ef52f85aba2417ef4c5b23",
      "tree": "317fc5fc59613b658daeb4060e808660467035b6",
      "parents": [
        "5b3b34c7602475de7ff547ca0ec835cf3ab1e791"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 04:17:38 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Mon Sep 21 18:49:39 2026 +0200"
      },
      "message": "Migrate GitHub to the native OAuth client\n\nChange-Id: Iece36b4ba5a197a7cc7b6d7bd506255d92c001d9\n"
    },
    {
      "commit": "5b3b34c7602475de7ff547ca0ec835cf3ab1e791",
      "tree": "35c93ba027f28575f37e20a78a93a398d1a33bd3",
      "parents": [
        "d058e1ccbe6bd4745f16570412850e4584459c70"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 04:17:11 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Mon Sep 21 18:49:39 2026 +0200"
      },
      "message": "Migrate Google to the native OAuth client\n\nChange-Id: I1d627d6760e6bd1542934fc9a35982b8300cdd7c\n"
    },
    {
      "commit": "d058e1ccbe6bd4745f16570412850e4584459c70",
      "tree": "7a2919849e59ac7d413ac98023e60dd6c5b76fd4",
      "parents": [
        "afe21eb9ff8904ef8327b3e0f65ac01122e777a6"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 04:16:54 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Mon Sep 21 18:49:38 2026 +0200"
      },
      "message": "Migrate Azure AD to the native OAuth client\n\nChange-Id: Id1f857ea2da665979cf87f3c80f23dc140c483cc\n"
    },
    {
      "commit": "afe21eb9ff8904ef8327b3e0f65ac01122e777a6",
      "tree": "b4e0f24d1d0c9e3afd9e852d63f450b21fed0f27",
      "parents": [
        "510aaf2b9827507d1c06ff969bb6866c09929b10"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 04:16:39 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Mon Sep 21 18:49:38 2026 +0200"
      },
      "message": "Migrate the discovery provider to the native OAuth client\n\nChange-Id: I3af4e1bb409319e2e98c1afdf56ce1ebec334750\n"
    },
    {
      "commit": "510aaf2b9827507d1c06ff969bb6866c09929b10",
      "tree": "d8b75624d0ea60b579c187ee4922ab8e176127ec",
      "parents": [
        "9719dbd18316d6614a0155697e378f8ee4c34dfc"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 04:16:21 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Mon Sep 21 18:49:38 2026 +0200"
      },
      "message": "Migrate Cognito to the native OAuth client\n\nChange-Id: I7b3113764eb6a4a2709cdd8572fe4dba9130d177\n"
    },
    {
      "commit": "9719dbd18316d6614a0155697e378f8ee4c34dfc",
      "tree": "2aafac9f7d05edfb6c2c0800b5be7a82484451fd",
      "parents": [
        "f291fdf90a1056e9210f008f0fd9f22cfdab60cb"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 04:16:05 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Mon Sep 21 18:49:38 2026 +0200"
      },
      "message": "Migrate Dex to the native OAuth client\n\nChange-Id: Ifc5075a5a7268e3622773a805beeb61b52954edd\n"
    },
    {
      "commit": "f291fdf90a1056e9210f008f0fd9f22cfdab60cb",
      "tree": "34fb8496e478e91cb0e266f6c5da7578084e0a84",
      "parents": [
        "27f7fd855c49abc4c55d6bd3f60605f306c973d1"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 04:15:34 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Mon Sep 21 18:49:38 2026 +0200"
      },
      "message": "Migrate Authentik to the native OAuth client\n\nChange-Id: I3d677ab7932702dded7337a3fcb5f8cac414391c\n"
    },
    {
      "commit": "27f7fd855c49abc4c55d6bd3f60605f306c973d1",
      "tree": "2349d70bdd82b6ef292013e7230d28e297eb1793",
      "parents": [
        "4c8a3aea4830329b3f724a45526492d2fbb604df"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 04:15:21 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Mon Sep 21 18:49:38 2026 +0200"
      },
      "message": "Migrate Auth0 to the native OAuth client\n\nChange-Id: If8b2149496fcbb711d6d482a668c02ad80da7240\n"
    },
    {
      "commit": "4c8a3aea4830329b3f724a45526492d2fbb604df",
      "tree": "872145a0a7cc524b4c2f61f10b6d981d8ccd1bd0",
      "parents": [
        "ef67b30ca215d99f16be01d479e8c42309bcf624"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 04:15:08 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Mon Sep 21 18:49:38 2026 +0200"
      },
      "message": "Migrate Tuleap to the native OAuth client\n\nChange-Id: I0d2022d204ca1f8c2ebb3c5913ae2ee31193350e\n"
    },
    {
      "commit": "ef67b30ca215d99f16be01d479e8c42309bcf624",
      "tree": "c0ebffe89038900541d806866806b30ce484ac0d",
      "parents": [
        "d153684d242b59d8eba3d91075a5debbd7011863"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 04:14:54 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Mon Sep 21 18:49:38 2026 +0200"
      },
      "message": "Migrate LemonLDAP to the native OAuth client\n\nChange-Id: Ifa46df3f76dfc777152781996734e48fbefddd0a\n"
    },
    {
      "commit": "d153684d242b59d8eba3d91075a5debbd7011863",
      "tree": "c03df90ffca5528c297457c2c5dd1878a08f9dbd",
      "parents": [
        "1926c49f0d9c7fd3184a08cdc9058c2e9c132fe0"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 04:14:33 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Mon Sep 21 18:49:38 2026 +0200"
      },
      "message": "Migrate Phabricator to the native OAuth client\n\nChange-Id: Iefc36a6721696459f1f865f82e3c050500e1e581\n"
    },
    {
      "commit": "1926c49f0d9c7fd3184a08cdc9058c2e9c132fe0",
      "tree": "af84827a9e5cc60346f05af544a512e6478a5401",
      "parents": [
        "02f1001ac46e7d6d3d552e6f4f1e6f0197c16b7b"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 04:14:17 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Mon Sep 21 18:49:38 2026 +0200"
      },
      "message": "Migrate AirVantage to the native OAuth client\n\nChange-Id: I71bb86b6d1fff79031585c1bc666dc9061d62600\n"
    },
    {
      "commit": "02f1001ac46e7d6d3d552e6f4f1e6f0197c16b7b",
      "tree": "adf979666c467f55dca87fefd94c95802acb7dc4",
      "parents": [
        "3aea840415c2fee9f8fd602161c5195abc20456b"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 04:13:59 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Mon Sep 21 18:49:38 2026 +0200"
      },
      "message": "Migrate Facebook to the native OAuth client\n\nChange-Id: I08bf9a34a642f18f32c0e6c87e1b2dfc331766b6\n"
    },
    {
      "commit": "3aea840415c2fee9f8fd602161c5195abc20456b",
      "tree": "31f4ef9c07e2fc5a7c91ffd5843ee33a2b7163c6",
      "parents": [
        "fb5aacd3c9f3d2836e5e756dbcdac31974cbe5f6"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 04:13:31 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Mon Sep 21 18:49:38 2026 +0200"
      },
      "message": "Migrate CAS to the native OAuth client\n\nChange-Id: Ia32d9c86c940b202fb94edbdea04ee73354f4f8a\n"
    },
    {
      "commit": "fb5aacd3c9f3d2836e5e756dbcdac31974cbe5f6",
      "tree": "6051412c050409487643a8865c021b70c660c223",
      "parents": [
        "914b6bab3c11c6c228f103f4b5a1ad03db1ce167"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 04:12:54 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Mon Sep 21 18:49:38 2026 +0200"
      },
      "message": "Migrate Bitbucket to the native OAuth client\n\nChange-Id: I95b7e9e7ff74aed01f6e7bc37b7bc38cf0c8379d\n"
    },
    {
      "commit": "914b6bab3c11c6c228f103f4b5a1ad03db1ce167",
      "tree": "b5e194dfb2b0d839aae95004b490f81d2f842b36",
      "parents": [
        "3b1d24d969bfb0c68fee429d28c3c61d896195a2"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 04:09:03 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Mon Sep 21 18:49:18 2026 +0200"
      },
      "message": "Add native OAuth HTTP client\n\nAdd a self-contained native OAuth 2.0 client (HttpOAuthClient) built on\na small OAuthHttpTransport, with an OAuthProviderEndpoints descriptor and\nenums describing client-auth style, bearer placement and token-response\nformat. HttpOAuthClientFactory constructs one from plugin config. This is\nan alternative implementation of the OAuthClient boundary; no provider\nuses it yet, so ScribeJava remains the default path.\n\nChange-Id: I74051b0151375ad17f31202920651df058c35c71\n"
    },
    {
      "commit": "3b1d24d969bfb0c68fee429d28c3c61d896195a2",
      "tree": "b907e6847da8415f2413589e546521cb3e03085d",
      "parents": [
        "076006ac8630977194fee5b1ac67a51ca9d2ad69"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 04:53:22 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Mon Sep 21 18:48:41 2026 +0200"
      },
      "message": "Reorganize shared OAuth types into base, client and utils packages\n\nMove the OAuthClient boundary into a client package and the shared\nservice plumbing (AbstractOAuthService, StandardResource/StandardIdToken\nservices, config factory, provider-config annotation, external-id scheme)\ninto a base package, and JsonUtil into utils. Extract config-key names\ninto OAuthConfigKeys, and add no-op extension seams (token-verification\nand id-token-decode hooks, plus JsonUtil helpers) that later native\nproviders override. Existing providers are behavior-unchanged; this sets\nup per-provider migration to a native client.\n\nChange-Id: Ibe6923acfa154158c3cc0ed352af3e96b6f3454e\n"
    },
    {
      "commit": "076006ac8630977194fee5b1ac67a51ca9d2ad69",
      "tree": "a28c139956cba556e88e5b2c5f75ec9bd4dff8b2",
      "parents": [
        "ae776a8f3f1731453a49ca3ddbb3db3df76b8820"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 20 03:38:18 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Mon Sep 21 18:48:38 2026 +0200"
      },
      "message": "Add OIDC JWT/JWKS validation library\n\nIntroduce a self-contained OIDC ID-token validation library: an\nOidcJwtValidator that verifies RS256-signed ID tokens against a\nprovider\u0027s JWKS, a JwksCache that fetches and caches signing keys, and\na ValidatedClaims value type. Add the OAuthUrls helper the validator\nuses to derive issuer/JWKS endpoints. This is a foundation for\nmigrating providers to the native OAuth client; nothing installs it yet.\n\nChange-Id: I0262a1cd6603329c17d52e2e1b78e9444aa85ccb\n"
    },
    {
      "commit": "ae776a8f3f1731453a49ca3ddbb3db3df76b8820",
      "tree": "22029d6588ace4c44592b564cea24fbb5727d9e1",
      "parents": [
        "2e3f76a4b756813765c53bc6ab27f452a27ca67c"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 06 15:16:22 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Mon Sep 07 14:40:25 2026 +0200"
      },
      "message": "Migrate sap to the OAuthClient boundary\n\nSAP IAS was the last provider still holding a raw OAuth20Service. Its\nstandard OAuth flow needs nothing SAP-specific: PKCE authorization and\ntoken exchange already live in the client, so SAPIasOAuthService now\nextends AbstractOAuthService and keeps only its own getUserInfo, which\nvalidates the SAP id_token via the CombiningValidator.\n\nThe one capability the client lacked is the resource-owner password\ngrant the login provider uses. Add passwordGrant to OAuthClient;\ngetAccessToken(user, password) delegates to it and returns an\nOAuthToken, so SAPIasOAuthLoginProvider no longer passes ScribeJava\u0027s\nOAuth2AccessToken around. A presented bearer secret is wrapped as the\ntoken\u0027s id_token so getUserInfo extracts it exactly as before.\n\nNo SAP class imports a ScribeJava request, response or token type now.\n\nChange-Id: I01215eeffd30cbaa63e74ecbcdc3ec242d5995ce\n"
    },
    {
      "commit": "2e3f76a4b756813765c53bc6ab27f452a27ca67c",
      "tree": "8a262f9ac7332b346adac258249c57b90a79ba41",
      "parents": [
        "5815fd75be91642abff916c60a086986249b46bf"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 06 14:13:26 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Mon Sep 07 14:40:25 2026 +0200"
      },
      "message": "Add PKCE to the client and migrate discovery\n\nPKCE needs ScribeJava\u0027s OAuth20Service (createAuthorizationUrlBuilder,\ninitPKCE), which lives inside the client and is hidden by the\nOAuthClient boundary. A base class could not perform PKCE, only\nre-delegate to the client, so the logic belongs in ScribeOAuthClient:\nwhen enabled, getAuthorizationInfo initializes PKCE and carries the\nper-login verifier; the token exchange already replays it. The verifier\nis generated per call and never retained.\n\ncreateClient gains an enablePkce opt-in alongside tolerateMissingToken\nType; the defaults are unchanged, so no other provider is affected.\n\nDiscovery becomes a StandardResourceOAuthService: its userinfo fetch,\ntoken exchange, version and name come from the base, leaving only the\ndiscovery-document bootstrap, resourceUrl() and parseUserInfo(). Its\nPKCE is now a property of the client it creates. It no longer imports\nScribeJava request, response or token types.\n\nThe PKCE and token-type mechanics move to a new ScribeOAuthClientTest;\nDiscoveryOAuthServiceTest now exercises the provider over a mocked\nOAuthClient and asserts it opts into PKCE.\n\nChange-Id: Ic88c10f046caa2b20b9c96f499a34b86cf17ef2f\n"
    },
    {
      "commit": "5815fd75be91642abff916c60a086986249b46bf",
      "tree": "7783cc9a54ed7ef9c5ced43293897e0a3987f11d",
      "parents": [
        "730d5b11577a8b5e06f11d577266371e71162ad6"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 06 13:48:30 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 06 17:14:32 2026 +0200"
      },
      "message": "Migrate facebook to StandardResourceOAuthService\n\nFacebook is a resource-fetcher: it reads graph.facebook.com/me and maps\nid/email/name to OAuthUserInfo, with email doubling as the login. Its\nonly non-standard aspect was the fields\u003demail,name query parameter,\nadded via ScribeJava\u0027s addQuerystringParameter, which percent-encodes\nthe comma.\n\nFold that into the resourceUrl() seam by encoding the same value, so the\nrequest is byte-identical on the wire (fields\u003demail%2Cname) while the\nfetch, token exchange, version and name come from the base. The provider\nno longer imports ScribeJava request, response or token types.\n\nChange-Id: I807aedd73938858b826b2cae629aa9585423d485\n"
    },
    {
      "commit": "730d5b11577a8b5e06f11d577266371e71162ad6",
      "tree": "73ac73eff99f7f4ceca343e9ed21b22f9e0cab88",
      "parents": [
        "1ef8a99a4d58ea235cb65ea66b27bd154f100a6d"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 06 13:46:48 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 06 17:14:30 2026 +0200"
      },
      "message": "Migrate cas to StandardResourceOAuthService\n\nCAS is a resource-fetcher: it reads %s/oauth2.0/profile and maps id\nplus the attributes array to OAuthUserInfo. The only reason it could\nnot share the standard token exchange was its defensive handling of a\nmissing token_type, which the standard path would reject because\nOAuthToken forbids a null secret.\n\nRather than change that shared behaviour for every provider, the\nclient gains an opt-in: createClient(..., tolerateMissingTokenType).\nWhen set it stores an absent token_type as the empty string, exactly\nwhat CAS did before; the default is unchanged, so every other provider\nkeeps ScribeJava\u0027s value. CAS opts in and needs no getAccessToken\noverride.\n\nBehaviour is otherwise preserved: same profile URL, same id and\nattribute parsing, same fix-legacy-user-id claimedIdentity.\n\nChange-Id: I0360e69ceb6dfaa3616463001690271348f2559f\n"
    },
    {
      "commit": "1ef8a99a4d58ea235cb65ea66b27bd154f100a6d",
      "tree": "ad4ac4debe7f9d891c50c275b596d560521beddf",
      "parents": [
        "922ca5e7311959deba5f8a9fd4145b069c9c79bb"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 06 13:34:07 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 06 17:14:03 2026 +0200"
      },
      "message": "Consolidate shared plumbing into AbstractOAuthService\n\nToken exchange, the authorization redirect, the version and the name\nwere repeated in both StandardResourceOAuthService and\nStandardIdTokenOAuthService. Pull them into a common\nAbstractOAuthService that both now extend, so the four methods and the\nclient/log/name state exist once.\n\nMigrate the two remaining hybrid providers, google and azure, onto the\nsame base with their own getUserInfo. Both fetch a resource and also\nvalidate a claim from the id_token: google matches the hosted\ndomain (hd), azure matches the tenant (tid) and audience (aud), and both\nreturn null to deny login on mismatch. They now fetch through\nOAuthClient instead of a raw OAuth20Service.\n\nGoogle keeps its authorization-redirect customization by overriding\ngetAuthorizationInfo to append the hd parameter.\n\nAzure needs its \"Accept: */*\" request header, so OAuthClient gains a\nget overload taking extra headers; the plain get delegates to it with\nnone. With this, google and azure no longer import ScribeJava request,\nresponse or token types.\n\nChange-Id: I2e263ee5f7ffca533a2ed92b396c77b83f44bade\n"
    },
    {
      "commit": "922ca5e7311959deba5f8a9fd4145b069c9c79bb",
      "tree": "70a7955b51fae4a5d37918e0bf66c05734f14866",
      "parents": [
        "899911a7db5de71a6f876f945cd6f296da04966c"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 06 13:28:44 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 06 17:12:19 2026 +0200"
      },
      "message": "Extract StandardIdTokenOAuthService for dex and keycloak\n\nDex and Keycloak do not fetch a userinfo resource: they decode the\nid_token JWT carried in the token response and read the claims from\nit. Factor that shared boilerplate (extract id_token, base64url-decode\nthe payload, parse the claim object) into a new base class, alongside\nthe token exchange, authorization redirect, version and name plumbing\nthat mirrors StandardResourceOAuthService.\n\nSubclasses keep only their own claim mapping via parseClaims(): dex\nstrips the configured domain from the email to form the username;\nkeycloak honours use-preferred-username and validates the required\nclaims. Behaviour is otherwise unchanged.\n\nThe debug log of the decoded claim object, previously only in\nkeycloak, now runs for both providers; it is debug-level only.\n\nThe temporary duplication of the four shared methods between the two\nbase classes is removed in the follow-up AbstractOAuthService change.\n\nChange-Id: I0268bcb0ff393a109fb841ff0327d701460137f1\n"
    },
    {
      "commit": "899911a7db5de71a6f876f945cd6f296da04966c",
      "tree": "38a9d848f1bb95b462013bd41d8c04413cd4d48c",
      "parents": [
        "d1dfe0d84f37d5266b4d4255e9765063c720f01f"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 06 13:26:24 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 06 17:12:03 2026 +0200"
      },
      "message": "Migrate cognito, auth0, authentik to StandardResourceOAuthService\n\nThese three OpenID Connect providers are plain resource-fetchers:\neach signs a GET to its userinfo endpoint and maps the JSON claims\n(sub, preferred_username, email, name) to OAuthUserInfo. That is\nexactly what StandardResourceOAuthService already does, so collapse\nthem to a constructor plus resourceUrl() and parseUserInfo(), the\nsame shape as the change-3 providers.\n\nBehaviour is preserved: same userinfo URLs, same claim mapping, and\nthe same claimedIdentity rules (cognito/authentik gate \"gerrit:\" +\nusername on link-to-existing-gerrit-account; auth0 uses sub).\n\nOne incidental fix: cognito previously logged under\nGitHubOAuthService (a copy-paste leftover); via the base logger it\nnow logs under its own class.\n\nCognitoOAuthServiceTest no longer reflects on a private \"service\"\nfield, which no longer exists. It stubs the client factory to return\na mock OAuthClient, matching the seam used by the other providers.\n\nChange-Id: Ib6970cbcb81b9e544a06bd84b3025e1b26f51040\n"
    },
    {
      "commit": "d1dfe0d84f37d5266b4d4255e9765063c720f01f",
      "tree": "aaffccee30d19c6d34149247b36d58309f7a8400",
      "parents": [
        "61d1cca10cee68c186d845f841cf28c5b8482d81"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 06 14:55:28 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 06 17:11:44 2026 +0200"
      },
      "message": "Extract StandardResourceOAuthService for resource providers\n\ngithub, bitbucket, gitlab, tuleap, phabricator, airvantage and lemon\neach fetch a userinfo resource with the access token and map the JSON\nto OAuthUserInfo. Move that shared flow behind OAuthClient and a new\nStandardResourceOAuthService base: token exchange, the authorization\nredirect, the version and the fetch itself happen once, leaving each\nprovider only its resource URL and response mapping.\n\nOAuthClient gains getVersion so the service version comes from the\nclient, and get() throws on a non-2xx response, collapsing the several\nper-provider error paths into one.\n\nThe client is assigned in the subclass constructor rather than passed\nto super(), because super() runs before the provider has read its\nconfig. None of the seven providers import com.github.scribejava.*\nany more.\n\nChange-Id: I22d8333b0913f2ffec70e7f616fdefb940e41394\n"
    },
    {
      "commit": "61d1cca10cee68c186d845f841cf28c5b8482d81",
      "tree": "a0d63a9c1ffb649705752e36ff0b69465f736ba6",
      "parents": [
        "fb6b3fa671153ad3378d60be5a67620f408557d4"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 06 12:24:28 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Sep 06 17:11:23 2026 +0200"
      },
      "message": "Introduce OAuthClient boundary and migrate GitHub to it\n\nProviders drive ScribeJava\u0027s request/response API directly and all do it\nthe same sign-execute-check-parse way. Add a plugin-internal OAuthClient\ninterface, implement it once over ScribeJava (ScribeOAuthClient), and\nmigrate the GitHub provider to it. ScribeJava, behaviour and\nconfiguration all stay.\n\nThe factory gains createClient(...) beside create(...); it delegates to\ncreate(...), so there is one ServiceBuilder chain and unmigrated\nproviders are untouched. create(...) is deleted in a later change once\nno caller remains.\n\nGitHubOAuthService no longer imports any com.github.scribejava.* type:\nrequest construction, token conversion, signing, execution, the status\ncheck and error formatting move into ScribeOAuthClient; only the JSON\nparse and GitHub-specific field mapping stay. It now overrides the\npost-PKCE getAuthorizationInfo() and getAccessToken(verifier,\ncodeVerifier) forms, which is how core calls them.\n\nChange-Id: I9c163a4c86f59107165c9966b2bc44b3fb2a1d1b\n"
    },
    {
      "commit": "fb6b3fa671153ad3378d60be5a67620f408557d4",
      "tree": "ac99ca8d1f1dfcf9774db22ff554fa28e125b63b",
      "parents": [
        "2d02e607ed0c00557cc6ad7b45d98b05ce9330a1"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Thu Apr 23 20:23:28 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Apr 28 01:21:25 2026 -0700"
      },
      "message": "Bazel: switch oauth BUILD to native ext_deps support\n\nUse native `ext_deps` support in `gerrit_plugin()` and\n`gerrit_plugin_tests()` in the oauth plugin BUILD file.\n\nDeclare external dependencies as Maven coordinates instead of generated\nBazel labels, and share common test dependencies through `EXT_DEPS`.\n\nThis removes repeated `@oauth_plugin_deps//...` labels, avoids explicit\ntest target naming and manual `:oauth__plugin` wiring, and drops the\nseparate call to `gerrit_plugin_dependency_tests()`.\n\nChange-Id: Ib076fc310be6b0b75b17dff7d80e25defdd2b728\n"
    },
    {
      "commit": "2d02e607ed0c00557cc6ad7b45d98b05ce9330a1",
      "tree": "727829865e6d6e42f708e65d0568a6cfcd102674",
      "parents": [
        "7eb61bb2e58358771b602f4d0da169c602ad5615",
        "eb885641b41e533b908ff9743ccb0676938e5b7b"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Thu Apr 23 14:51:07 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Thu Apr 23 14:51:07 2026 +0200"
      },
      "message": "Merge branch \u0027stable-3.14\u0027\n\n* stable-3.14:\n  Discovery OAuth: Validate discovery config and add tests\n  Discovery OAuth: support generic OAuth via well-known discovery URL\n  Bump scribejava to 8.3.3 and jackson to 2.21.1\n\nChange-Id: I9f8bed23c9ad1e6507a167c74d7d982575c328bc\n"
    },
    {
      "commit": "eb885641b41e533b908ff9743ccb0676938e5b7b",
      "tree": "11f7639708fcb0f4514578ec4482fa8a5052dac6",
      "parents": [
        "3b1b501f90181a0b84bf625d91f2235177c21907"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Mar 22 10:08:12 2026 +0100"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Apr 21 10:22:34 2026 +0200"
      },
      "message": "Discovery OAuth: Validate discovery config and add tests\n\nRefactor the DiscoveryOAuthService to improve robustness and\nmaintainability.\n\n* Validation:\n  - Add validateRootUrl to ensure the configured root-url is valid and\n    uses http/https.\n  - Add validateDiscoveryDocument to verify that the provider\u0027s\n    response contains all required OIDC endpoints (issuer, auth,\n    token, and userinfo) and that they are absolute URLs.\n  - Automatically trim trailing slashes from the root-url to prevent\n    double-slashes in the final discovery path.\n  - Add null-safety checks in DiscoveryApi.\n\n* Performance:\n  - Use Guava\u0027s CharStreams for more efficient stream-to-string\n    conversion, replacing manual BufferedReader loops.\n\n* Testing:\n  - Add DiscoveryApiTest for unit testing the ScribeJava API bridge.\n  - Add DiscoveryOAuthServiceTest with high coverage, including\n    mocking the discovery process and testing various failure modes\n    (malformed URLs, missing JSON fields, and HTTP errors).\n\nFeature: https://github.com/davido/gerrit-oauth-provider/issues/134\nChange-Id: I961c0a0e13511c4134e24a98c36e83aa12ea5c3c\n"
    },
    {
      "commit": "3b1b501f90181a0b84bf625d91f2235177c21907",
      "tree": "02bb5d49e3c54b7d10b8ab43b06e87c5a07a5efd",
      "parents": [
        "c3a06e3f5b8d42d78625cdd2983b725c90e10b2b"
      ],
      "author": {
        "name": "Kai Liu",
        "email": "kraml.liu@gmail.com",
        "time": "Sat Mar 21 11:49:38 2026 +0800"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Apr 21 10:22:10 2026 +0200"
      },
      "message": "Discovery OAuth: support generic OAuth via well-known discovery URL\n\nThis is ported from https://github.com/davido/gerrit-oauth-provider/pull/179,\nwith below changes:\n\n  - Adapt to the latest master branch.\n  - Formatted by GJF to follow the project style.\n  - Add doc.\n  - Translated Chinese code comments to English.\n\nCredit goes to the origin author @Philogag.\n\nFeature: https://github.com/davido/gerrit-oauth-provider/issues/134\nChange-Id: I2145a365cc9ddc21972a7c66d87aabd4cb1c1eb8\nSigned-off-by: Kai Liu \u003ckraml.liu@gmail.com\u003e\n"
    },
    {
      "commit": "c3a06e3f5b8d42d78625cdd2983b725c90e10b2b",
      "tree": "52eda54a83b86779107bc433a038fe03007f37b9",
      "parents": [
        "e53ff8dd02d0c818df6ec1a5944b340005e2c194"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Jul 14 16:04:57 2024 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Apr 21 10:22:00 2026 +0200"
      },
      "message": "Bump scribejava to 8.3.3 and jackson to 2.21.1\n\nUpdate ScribeJava and Jackson Databind to newer versions.\n\nWith ScribeJava 8.x, Java 8 specific functionality has been moved to a\nseparate \u0027scribejava-java8\u0027 module. Since this is now a transitive\ndependency of scribejava-apis, we update the dependency lockfile and\ninclude it in our third-party runtime JARs allowlist to ensure it is\ncorrectly bundled into the plugin artifact.\n\nThe Jackson bump ensures compatibility with the newer ScribeJava release\nand addresses potential security vulnerabilities in the older 2.10.x\nline.\n\nChange-Id: I27a4a1946b3f3e0eecf6dfd045d854cdd80dcb76\n"
    },
    {
      "commit": "7eb61bb2e58358771b602f4d0da169c602ad5615",
      "tree": "727829865e6d6e42f708e65d0568a6cfcd102674",
      "parents": [
        "38eaa22d3d238942ff176a06e740ffd7f349f643"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Thu Apr 16 04:48:53 2026 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Thu Apr 16 04:48:53 2026 +0200"
      },
      "message": "Reduce boilerplate code by using gerrit_plugin_dependency_tests\n\nChange-Id: Id46b6ab88450c6dbf8850e7f3ba8f9f8efbddfa1\n"
    },
    {
      "commit": "38eaa22d3d238942ff176a06e740ffd7f349f643",
      "tree": "99b964dae231a4b2f079833acd92596cdbc750e6",
      "parents": [
        "1ee68cbd415aa4082d0808b6883189f65d1632ed"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sat Mar 21 13:53:39 2026 +0800"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Thu Apr 16 04:42:23 2026 +0200"
      },
      "message": "Discovery OAuth: Add optional PKCE support\n\nAdd support for Proof Key for Code Exchange (PKCE) in the Discovery\nOAuth provider to improve security of the authorization code flow.\n\nWhen `enable-pkce \u003d true`:\n- Generate a PKCE code verifier/challenge during authorization\n- Return verifier alongside the authorization URL\n- Include verifier when exchanging the authorization code for a token\n\nThis is disabled by default to preserve backward compatibility with\nproviders that do not support PKCE.\n\nNOTE: This change depends on a Gerrit core update that extends the\nOAuthServiceProvider API (OAuthAuthorizationInfo and PKCE-aware\ngetAccessToken). The plugin will not work with older Gerrit versions.\n\nAlso:\n- Update configuration and documentation\n- Add unit tests covering PKCE authorization and token exchange flows\n\nContributed-By: Kai Liu \u003ckraml.liu@gmail.com\u003e\nChange-Id: I56fa0f4d50333a2c568d95c31c78f2de3afed661\n"
    },
    {
      "commit": "1ee68cbd415aa4082d0808b6883189f65d1632ed",
      "tree": "902b794748a6ccece43131aa3d2075f1a7d02a7a",
      "parents": [
        "775e886efab693987170bead272f86159ea3fd1a",
        "f255dcc44146a48eb9121133a46dd14cf1b1aeb9"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david.ostrovsky@gmail.com",
        "time": "Tue Apr 14 03:06:20 2026 -0700"
      },
      "committer": {
        "name": "Gerrit Code Review",
        "email": "noreply-gerritcodereview@google.com",
        "time": "Tue Apr 14 03:06:20 2026 -0700"
      },
      "message": "Merge \"[SAP IAS] Fix thread-safety race condition in PKCE handling\""
    },
    {
      "commit": "775e886efab693987170bead272f86159ea3fd1a",
      "tree": "11f7639708fcb0f4514578ec4482fa8a5052dac6",
      "parents": [
        "42bd33146977e837e0a33aa08dc759e0ef72fae1"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Mar 22 10:08:12 2026 +0100"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Mon Mar 23 09:01:17 2026 +0100"
      },
      "message": "Discovery OAuth: Validate discovery config and add tests\n\nRefactor the DiscoveryOAuthService to improve robustness and\nmaintainability.\n\n* Validation:\n  - Add validateRootUrl to ensure the configured root-url is valid and\n    uses http/https.\n  - Add validateDiscoveryDocument to verify that the provider\u0027s\n    response contains all required OIDC endpoints (issuer, auth,\n    token, and userinfo) and that they are absolute URLs.\n  - Automatically trim trailing slashes from the root-url to prevent\n    double-slashes in the final discovery path.\n  - Add null-safety checks in DiscoveryApi.\n\n* Performance:\n  - Use Guava\u0027s CharStreams for more efficient stream-to-string\n    conversion, replacing manual BufferedReader loops.\n\n* Testing:\n  - Add DiscoveryApiTest for unit testing the ScribeJava API bridge.\n  - Add DiscoveryOAuthServiceTest with high coverage, including\n    mocking the discovery process and testing various failure modes\n    (malformed URLs, missing JSON fields, and HTTP errors).\n\nFeature: https://github.com/davido/gerrit-oauth-provider/issues/134\nChange-Id: I961c0a0e13511c4134e24a98c36e83aa12ea5c3c\n"
    },
    {
      "commit": "42bd33146977e837e0a33aa08dc759e0ef72fae1",
      "tree": "02bb5d49e3c54b7d10b8ab43b06e87c5a07a5efd",
      "parents": [
        "a9a4be6afcbc1910372031bed43287edd3aae6e1"
      ],
      "author": {
        "name": "Kai Liu",
        "email": "kraml.liu@gmail.com",
        "time": "Sat Mar 21 11:49:38 2026 +0800"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Mon Mar 23 08:55:32 2026 +0100"
      },
      "message": "Discovery OAuth: support generic OAuth via well-known discovery URL\n\nThis is ported from https://github.com/davido/gerrit-oauth-provider/pull/179,\nwith below changes:\n\n  - Adapt to the latest master branch.\n  - Formatted by GJF to follow the project style.\n  - Add doc.\n  - Translated Chinese code comments to English.\n\nCredit goes to the origin author @Philogag.\n\nFeature: https://github.com/davido/gerrit-oauth-provider/issues/134\nChange-Id: I2145a365cc9ddc21972a7c66d87aabd4cb1c1eb8\nSigned-off-by: Kai Liu \u003ckraml.liu@gmail.com\u003e\n"
    },
    {
      "commit": "a9a4be6afcbc1910372031bed43287edd3aae6e1",
      "tree": "52eda54a83b86779107bc433a038fe03007f37b9",
      "parents": [
        "e53ff8dd02d0c818df6ec1a5944b340005e2c194"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Jul 14 16:04:57 2024 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Mar 22 21:25:50 2026 +0100"
      },
      "message": "Bump scribejava to 8.3.3 and jackson to 2.21.1\n\nUpdate ScribeJava and Jackson Databind to newer versions.\n\nWith ScribeJava 8.x, Java 8 specific functionality has been moved to a\nseparate \u0027scribejava-java8\u0027 module. Since this is now a transitive\ndependency of scribejava-apis, we update the dependency lockfile and\ninclude it in our third-party runtime JARs allowlist to ensure it is\ncorrectly bundled into the plugin artifact.\n\nThe Jackson bump ensures compatibility with the newer ScribeJava release\nand addresses potential security vulnerabilities in the older 2.10.x\nline.\n\nChange-Id: I27a4a1946b3f3e0eecf6dfd045d854cdd80dcb76\n"
    },
    {
      "commit": "f255dcc44146a48eb9121133a46dd14cf1b1aeb9",
      "tree": "e0a2cad3e67f0e9e24a0a51cf2b72d1d0f1a0380",
      "parents": [
        "e53ff8dd02d0c818df6ec1a5944b340005e2c194"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Mar 22 19:45:41 2026 +0100"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Mar 22 21:01:09 2026 +0100"
      },
      "message": "[SAP IAS] Fix thread-safety race condition in PKCE handling\n\nThe previous implementation used a shared AuthorizationUrlBuilder field\nin the SAPIasOAuthService singleton. Calling initPKCE() on this shared\nbuilder meant that concurrent login requests from different users would\noverwrite the code_verifier, leading to intermittent authentication\nfailures.\n\nUse the new OAuthAuthorizationInfo extension point to generate and\nreturn a per-request code_verifier. This allows Gerrit to store the\nverifier in the user\u0027s session and pass it back to the\ngetAccessToken(OAuthVerifier, String) method, ensuring the verifier\nmatches the original challenge for each specific login flow.\n\nThe single-argument getAccessToken(OAuthVerifier) and\ngetAuthorizationUrl() methods are removed as they are now provided by\ndefault implementations in the OAuthServiceProvider interface.\n\nAdd SAPIasOAuthServiceTest to verify the PKCE flow and ensure that the\ncode verifier is correctly extracted from the session and passed to the\nunderlying ScribeJava service.\n\nDepends-On: https://gerrit-review.googlesource.com/c/gerrit/+/564343\nChange-Id: I718ec9d72da1c13ca4ac405563a8d4c4a5636b8e\n"
    },
    {
      "commit": "e53ff8dd02d0c818df6ec1a5944b340005e2c194",
      "tree": "a8b7d1a3d6504910220adc95ddb1698d59aa3779",
      "parents": [
        "9ecc49bc156a395ed06b65a854860145511ed332"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Feb 15 10:21:02 2026 +0100"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sat Mar 21 03:26:54 2026 -0700"
      },
      "message": "Bazel: compare runtime overlap against headless Gerrit WAR\n\nAdd a guardrail that fails if the oauth plugin bundles third-party\nruntime jars that are already provided by Gerrit.\n\nUse //:headless.war.jars.txt as the comparison manifest instead of\n//:release.war.jars.txt.\n\nThe release WAR is not the right boundary for this check because it also\nincludes the packaged core plugins via //plugins:core. Comparing against\nthat manifest would make this test depend on the full set of core plugin\nsubmodules being present during Bazel analysis.\n\nIn CI/CD the plugin is built inside a partial Gerrit clone without\nfetching the core plugin submodules. Using the release WAR manifest\nwould therefore fail analysis before the test can run.\n\nThe headless WAR already provides the correct comparison scope for this\nguardrail: jars shipped by Gerrit itself, but not jars contributed by\nthe packaged core plugins. This keeps the overlap check focused on\nlibraries provided by Gerrit runtime, while avoiding an unnecessary\ndependency on core plugin submodules.\n\nThe test remains Gerrit-tree-only and is gated via:\n\n  target_compatible_with \u003d in_gerrit_tree_enabled()\n\nso standalone plugin builds continue to report it as SKIPPED.\n\nChange-Id: I4abd5646b9a92f3ab619c74c72bf4c47bbcdc07f\n"
    },
    {
      "commit": "9ecc49bc156a395ed06b65a854860145511ed332",
      "tree": "c4fc23f9a930bed2fcd32de138c499d0884e1212",
      "parents": [
        "2134c3482c1382f85d05c38f010310de4e944cc3"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sat Feb 14 14:45:10 2026 +0100"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sat Mar 21 03:26:19 2026 -0700"
      },
      "message": "Add allowlist test for packaged runtime JARs\n\nTrack the set of third-party runtime dependencies that are bundled into\nthe oauth plugin by generating a deterministic manifest for\n:oauth__plugin and diffing it against an allowlist in CI.\n\nThis prevents accidental changes to the packaged dependency set and\nensures that libraries already provided by Gerrit are not bundled into\nthe plugin.\n\nExclude org.slf4j:slf4j-api from the Maven dependencies since Gerrit\nships it, avoiding duplicate classes and potential version skew in the\nplugin classloader.\n\nChange-Id: I625bd7f0d4a29ff68996b295562b5349ef4b7c55\n"
    },
    {
      "commit": "2134c3482c1382f85d05c38f010310de4e944cc3",
      "tree": "ed72c9503a79fc6ce62572119604865dfa2d6344",
      "parents": [
        "5c230cddbac5ac7c83b102c0e4b83237b0d37a1b"
      ],
      "author": {
        "name": "Thomas Dräbing",
        "email": "thomas.draebing@sap.com",
        "time": "Wed Nov 12 09:19:59 2025 +0100"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sat Mar 21 03:25:50 2026 -0700"
      },
      "message": "Adapt to Gerrit\u0027s use of bazel modules\n\nTurn off strict_visibility in the rules_jvm_external maven_install used\nfor @external_plugin_deps.\n\nWith strict_visibility enabled, transitively resolved Maven artifacts\nare generated with //visibility:private and cannot be referenced\ndirectly from plugin BUILD targets. This conflicts with Bazel strict-\ndeps, which requires direct dependencies to be listed when their types\nare used at compile time.\n\nFor example, scribejava-apis depends transitively on scribejava-core,\nbut plugin sources extending DefaultApi20 must add\n@external_plugin_deps//:com_github_scribejava_scribejava_core as a\ndirect dependency to satisfy strict-deps. With strict_visibility enabled\nthis fails due to visibility restrictions.\n\nDisabling strict_visibility allows depending on such transitively\nresolved artifacts directly, while still keeping strict-deps enabled to\nenforce explicit compile-time dependencies.\n\nTo support both standalone and in-tree build modes, split the Maven\nrepositories into:\n\n  * a shared \"external_plugin_deps\" repository that contains only\n    Gerrit-provided APIs (gerrit-plugin-api and acceptance framework)\n    and does not define a lock file\n\n  * a plugin-specific repository (\"oauth_plugin_deps\") that contains\n    the plugin\u0027s bundled runtime dependencies and owns its lock file\n\nThis allows:\n\n  - bazlets to continue referencing @external_plugin_deps for\n    Gerrit API dependencies in standalone mode without bundling\n    them into the plugin\n\n  - plugin runtime dependencies to remain reproducible via\n    lock files\n\n  - multiple plugins to coexist in an in-tree build without\n    contributing conflicting lock files for the same repository\n\nProvide a MODULE.bazel fragment that can be linked into Gerrit\u0027s\n`plugins/external_plugin_deps.MODULE.bazel` when the plugin is built\ninside the Gerrit source tree.\n\nThis allows the plugin to be built in-tree without modifying Gerrit\u0027s\nmain module configuration beyond including this fragment.\n\nUpdate the build documentation to describe how to link the fragment\nand run plugin tests in this configuration.\n\nChange-Id: Ib3e8ee4012c8180131b26622dfacc29e31834646\n"
    },
    {
      "commit": "5c230cddbac5ac7c83b102c0e4b83237b0d37a1b",
      "tree": "dca9b59622b7d6b3988001d3be1775e3f8e28cff",
      "parents": [
        "649112608cfead3910381058e00615def3be9677"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Mar 17 14:59:53 2026 +0100"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Mar 17 15:03:28 2026 +0100"
      },
      "message": "Bazel: Remove unused commons-codec dependency\n\nCommit I033936936b removed the usage of commons-codec, but the Bazel\ndefinition in external_plugin_deps.bzl was left behind.\n\nRemove the stale maven_jar and the omit_commons_codec flag.\n\nChange-Id: I94ab423bd0ffe2b7d3cb9d3ad1c119c309368aa6\n"
    },
    {
      "commit": "649112608cfead3910381058e00615def3be9677",
      "tree": "a1a395629018fd72af85f702c75b04092e466dc7",
      "parents": [
        "b49e40ad37864423bad97584692b032922e2f040"
      ],
      "author": {
        "name": "Thomas Dräbing",
        "email": "thomas.draebing@sap.com",
        "time": "Mon Sep 29 13:31:57 2025 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Mar 17 13:44:50 2026 +0100"
      },
      "message": "Reduce duplicated code to build OAuth20Service\n\nChange-Id: I0e70cbe305ca5bc48c77c1c17aeb58026cd902b9\n"
    },
    {
      "commit": "b49e40ad37864423bad97584692b032922e2f040",
      "tree": "132b940371da0078332a982e2ad42e868ef27ae5",
      "parents": [
        "62e16441ea3b73c1fe17a70f2f1eb89f0e0b5088"
      ],
      "author": {
        "name": "Thomas Dräbing",
        "email": "thomas.draebing@sap.com",
        "time": "Sat Jan 17 11:25:49 2026 +0100"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Tue Mar 17 13:43:07 2026 +0100"
      },
      "message": "Remove deprecated legacy naming of Azure AD (Office365)\n\nThis change removes support for the legacy \"office365\" OAuth provider\nnaming and configuration, which has been deprecated in 2021: I52e8834f5c\nin favor of the canonical \"azure\" provider.\n\nThe OAuth plugin now only exposes the Azure AD provider under the\n\"azure\" name. Configuration using the legacy \"office365\" provider name\nis no longer recognized.\n\nFor backward compatibility, linking of existing user identities is still\nsupported: when enabled, existing Gerrit accounts that were previously\ncreated using the \"office365\" external ID scheme can be linked to the\nnew \"azure\" external ID scheme during authentication. No new accounts\nare created using the deprecated scheme.\n\nAdministrators of sites that previously relied on the legacy Office365\nnaming should have had sufficient time to migrate their configuration to\nthe \"azure\" provider and, if necessary, enable identity linking to\npreserve existing user accounts.\n\nChange-Id: Ibf29c03f312bc2a3f978c824b8c79cbc81b84c65\n"
    },
    {
      "commit": "62e16441ea3b73c1fe17a70f2f1eb89f0e0b5088",
      "tree": "5378898cad2b43d653c7e32f222505102e5fe042",
      "parents": [
        "2807ae01c3c0b4886b2990e9e2b4d133f7fc5695"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Fri Feb 13 12:06:58 2026 +0100"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Fri Feb 13 13:43:46 2026 +0100"
      },
      "message": "Replace commons-codec Base64 with JDK Base64 for JWT decoding\n\nJWT tokens encode their header and payload using Base64URL as defined by\nRFC 7515/7519. The current implementation decodes JWT payloads using\neither org.apache.commons.codec.binary.Base64 or the standard Base64\ndecoder, neither of which implements the URL-safe Base64 variant required\nby the JWT specification. This may silently accept malformed input or\nfail for URL-safe payloads.\n\nReplace existing decoding logic with java.util.Base64.getUrlDecoder(),\nwhich correctly implements Base64URL, and apply the same decoding to\nSAP IAS JWT parsing, which previously used the standard Base64 decoder.\n\nAs part of this change:\n  * Decode JWT payloads using Base64.getUrlDecoder()\n  * Remove reliance on UnsupportedEncodingException by using\n    StandardCharsets.UTF_8 directly\n  * Maintain existing failure semantics for malformed JWT structure,\n    while treating invalid Base64URL payloads as IO failures.\n\nMalformed tokens that were previously accepted due to permissive\ndecoding will now be rejected.\n\nRemove the commons-codec dependency from the oauth plugin entirely.\n\nChange-Id: I033936936bdf88713e9eab604923215b0b57d4a7\n"
    },
    {
      "commit": "2807ae01c3c0b4886b2990e9e2b4d133f7fc5695",
      "tree": "50b7d61414b4b0e84758ac9092d161c983bd5ae7",
      "parents": [
        "b2fa29e18378779c335076fd99b6df3a5fc324cd",
        "ab0eb8c0e5dc58c4f21fca3e8ed3b28f0d7eca43"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david.ostrovsky@gmail.com",
        "time": "Thu Jan 15 08:58:22 2026 -0800"
      },
      "committer": {
        "name": "Gerrit Code Review",
        "email": "noreply-gerritcodereview@google.com",
        "time": "Thu Jan 15 08:58:22 2026 -0800"
      },
      "message": "Merge \"Remove unnecessary whitespaces before ? during init\""
    },
    {
      "commit": "ab0eb8c0e5dc58c4f21fca3e8ed3b28f0d7eca43",
      "tree": "72a2c5dfbf6c41e9d5a7a8a305046429a3ce8931",
      "parents": [
        "527b52384aaaf4f971a7826dc51be19cf9081eed"
      ],
      "author": {
        "name": "Thomas Dräbing",
        "email": "thomas.draebing@sap.com",
        "time": "Mon Sep 29 13:34:10 2025 +0200"
      },
      "committer": {
        "name": "Thomas Dräbing",
        "email": "thomas.draebing@sap.com",
        "time": "Thu Nov 27 05:07:48 2025 -0800"
      },
      "message": "Remove unnecessary whitespaces before ? during init\n\nChange-Id: I6cc4acc63d4baade4acb77b4c15760233d8f2f17\n"
    },
    {
      "commit": "b2fa29e18378779c335076fd99b6df3a5fc324cd",
      "tree": "1e44be833b8df4663553dd29b2dfb711fb10d120",
      "parents": [
        "527b52384aaaf4f971a7826dc51be19cf9081eed"
      ],
      "author": {
        "name": "Thomas Dräbing",
        "email": "thomas.draebing@sap.com",
        "time": "Thu May 22 09:52:24 2025 +0200"
      },
      "committer": {
        "name": "Thomas Dräbing",
        "email": "thomas.draebing@sap.com",
        "time": "Wed Oct 15 04:03:36 2025 -0700"
      },
      "message": "[SAP IAS] Validate SAP IAS token during login with token\n\nThis change uses the official validation tools provided by SAP IAS\nto verify that the token is valid for the requested application.\n\nChange-Id: I56a5044566741539d8b0d236ea18d868568cf09c\n"
    },
    {
      "commit": "527b52384aaaf4f971a7826dc51be19cf9081eed",
      "tree": "556fdff7d281a195f01295f5e1965c6c4b7a79a1",
      "parents": [
        "74475759a21c1a47c7b4339de358b7894756ac1d"
      ],
      "author": {
        "name": "Thomas Dräbing",
        "email": "thomas.draebing@sap.com",
        "time": "Mon Jan 27 12:18:41 2025 +0100"
      },
      "committer": {
        "name": "Thomas Dräbing",
        "email": "thomas.draebing@sap.com",
        "time": "Tue Sep 30 11:24:42 2025 +0200"
      },
      "message": "[SAP IAS] Optionally allow the Resource Owner Password Flow\n\nChange-Id: If8a57ac4d487fece946b76a49fddeba3d63bc192\n"
    },
    {
      "commit": "74475759a21c1a47c7b4339de358b7894756ac1d",
      "tree": "6b4e76170dead29f81830b609cc5aef257fa8d45",
      "parents": [
        "e4ebdd73ac27b671764743dd3c051b100d8da7a2"
      ],
      "author": {
        "name": "Thomas Dräbing",
        "email": "thomas.draebing@sap.com",
        "time": "Fri Jan 24 14:30:47 2025 +0100"
      },
      "committer": {
        "name": "Thomas Dräbing",
        "email": "thomas.draebing@sap.com",
        "time": "Tue Sep 30 11:24:42 2025 +0200"
      },
      "message": "[SAP IAS] Add basic OAuth support for GitOverHttp\n\nThis allows to login with an OAuth token sent as a password.\n\nChange-Id: Iaec21b0e23b061601bc3e78aad72fca003be7672\n"
    },
    {
      "commit": "e4ebdd73ac27b671764743dd3c051b100d8da7a2",
      "tree": "8d197d27419647344a5d2e75a03643d727fdaeca",
      "parents": [
        "bd2bf69f93f68a1c20fbad27e0af5bdea5918ef4"
      ],
      "author": {
        "name": "Thomas Dräbing",
        "email": "thomas.draebing@sap.com",
        "time": "Fri Jan 24 15:36:07 2025 +0100"
      },
      "committer": {
        "name": "Thomas Dräbing",
        "email": "thomas.draebing@sap.com",
        "time": "Tue Sep 30 11:24:42 2025 +0200"
      },
      "message": "[SAP IAS] Add optional support for PKCE\n\nChange-Id: I3fcaedd58266fb7bf7aeef5274e14e16c8cffe25\n"
    },
    {
      "commit": "bd2bf69f93f68a1c20fbad27e0af5bdea5918ef4",
      "tree": "3109b41454c65677cd89418ecb495ff9fd7e323f",
      "parents": [
        "a175500df1b206f6736f99f7994f49f95af9f638"
      ],
      "author": {
        "name": "Christian Mathis",
        "email": "christian.mathis@sap.com",
        "time": "Fri Jan 17 21:06:13 2025 +0100"
      },
      "committer": {
        "name": "Thomas Dräbing",
        "email": "thomas.draebing@sap.com",
        "time": "Tue Sep 30 11:24:42 2025 +0200"
      },
      "message": "[SAP IAS] Add SAP Cloud Identity Services (IAS) oauth provider\n\nSee https://help.sap.com/docs/cloud-identity-services/cloud-identity-services/openid-connect\n\nChange-Id: Ibb637f51148ef20f2d79b8c88519be38ebc1da11\n"
    },
    {
      "commit": "a175500df1b206f6736f99f7994f49f95af9f638",
      "tree": "6f0dfdc6b465f41313320f9862005fda05139023",
      "parents": [
        "d946a36c162a6d746ecbcad0769043761454e389"
      ],
      "author": {
        "name": "Thomas Dräbing",
        "email": "thomas.draebing@sap.com",
        "time": "Wed Apr 23 16:14:32 2025 +0200"
      },
      "committer": {
        "name": "Thomas Dräbing",
        "email": "thomas.draebing@sap.com",
        "time": "Tue Sep 30 11:24:42 2025 +0200"
      },
      "message": "Set OAuth external ID on CreateAccount call\n\nTo create an account you either have to login via the UI or an admin has to\ncreate it via REST API. The former worked without issue, since OAuth is\ndirectly involved in account creation, i.e. the data returned by the\nidentity provider is being used to set up the account. However, it was not\npossible to create an account via REST API and then log into it via OAuth.\nThe reason was that the account created via REST API didn\u0027t get an external\nID on creation that linked it to the IDP. On authentication Gerrit would\nthus complain that the account exists and that the provided secret didn\u0027t\nmatch the stored password instead of contacting the OAuth server.\n\nGerrit provides an extension point where plugins can provide additional\nexternal IDs on account creation. This extension point is being implemented\nby this change.\n\nChange-Id: Ie643503f4e1c2247afd1674036aeaf3b33ca7665\n"
    },
    {
      "commit": "d946a36c162a6d746ecbcad0769043761454e389",
      "tree": "e272c4d4d5af29a4d01603b6a0f1e44535859f32",
      "parents": [
        "7b4248dd6d58d41728897836b2b0f809a9b2c05b"
      ],
      "author": {
        "name": "Thomas Dräbing",
        "email": "thomas.draebing@sap.com",
        "time": "Tue Apr 22 13:35:59 2025 +0200"
      },
      "committer": {
        "name": "Thomas Dräbing",
        "email": "thomas.draebing@sap.com",
        "time": "Tue Sep 30 11:24:40 2025 +0200"
      },
      "message": "Make more use of Guice to reduce boiler plate code\n\nThis also enforces a stricter adherence to naming conventions used by\nalmost all implemented OAuth providers.\n\nChange-Id: I5e394c2e0062507b0e14a07cf67e216c18d3355a\n"
    },
    {
      "commit": "7b4248dd6d58d41728897836b2b0f809a9b2c05b",
      "tree": "d76ed25c9bc7129be6b178815567c94b74e11b7d",
      "parents": [
        "29057163d504b604e098e6ad23c6c84d7148c6ff"
      ],
      "author": {
        "name": "Thomas Dräbing",
        "email": "thomas.draebing@sap.com",
        "time": "Wed May 28 10:40:14 2025 +0200"
      },
      "committer": {
        "name": "Thomas Dräbing",
        "email": "thomas.draebing@sap.com",
        "time": "Wed Sep 10 10:25:40 2025 +0200"
      },
      "message": "Sort OAuth implementations into packages\n\nChange-Id: I3ad158173adb11df6bf313df0dc1e08906d5f1d9\n"
    },
    {
      "commit": "29057163d504b604e098e6ad23c6c84d7148c6ff",
      "tree": "7bb5e75b55db25fe1c509c207904f9074a0796fd",
      "parents": [
        "f7d640c33c04af6294c0e53c7434bc11670b35fa"
      ],
      "author": {
        "name": "Thomas Dräbing",
        "email": "thomas.draebing@sap.com",
        "time": "Wed Sep 10 10:24:14 2025 +0200"
      },
      "committer": {
        "name": "Thomas Dräbing",
        "email": "thomas.draebing@sap.com",
        "time": "Wed Sep 10 10:24:41 2025 +0200"
      },
      "message": "Format with GJF 1.24.0\n\nChange-Id: I54b8a9e88f8b4f366475c347069bc96d2ae6d256\n"
    },
    {
      "commit": "f7d640c33c04af6294c0e53c7434bc11670b35fa",
      "tree": "d6e9b603079ae651659d4ad324b4861ac3bb9cd0",
      "parents": [
        "a8f67c80b446760cf080e0d0e0467ba629147ac6"
      ],
      "author": {
        "name": "Ishan Badgainya",
        "email": "ishan2796@gmail.com",
        "time": "Sun Apr 13 14:31:21 2025 +0530"
      },
      "committer": {
        "name": "ishan",
        "email": "ishan2796@gmail.com",
        "time": "Wed Jul 16 06:18:03 2025 -0700"
      },
      "message": "[Cognito OAuth]Support for link-to-existing-gerrit-accounts\n\nThis adds support for link-to-existing-gerrit-accounts to Cognito\nservice in OAuth plugin.\n\nThis adds a configuration option named link-to-existing-gerrit-accounts\nthat can be set to true to migrate to this provider from existing\nLDAP accounts by linking them with externalIDs instead of trying\nto create new accounts.\n\nChange-Id: I9724cf13efe7026f6959b5e585b9c465063cdf82\n"
    },
    {
      "commit": "a8f67c80b446760cf080e0d0e0467ba629147ac6",
      "tree": "02748efa11d73e03bc1f87da03f24be0f045c3d4",
      "parents": [
        "98231604d60788bb43490f1a301d792817ac8008"
      ],
      "author": {
        "name": "Saša Živkov",
        "email": "sasa.zivkov@sap.com",
        "time": "Fri Jan 24 16:54:02 2025 +0100"
      },
      "committer": {
        "name": "Saša Živkov",
        "email": "sasa.zivkov@sap.com",
        "time": "Wed Jan 29 12:15:42 2025 +0100"
      },
      "message": "Factor out some wide spread boilerplate code\n\nChange-Id: I9cf7e674d6499a09f8a15a3d8f55ec55157b5695\n"
    },
    {
      "commit": "98231604d60788bb43490f1a301d792817ac8008",
      "tree": "81a20219fa4bbf60f8996cb46d46ebc5ea0c11ee",
      "parents": [
        "f45c596896cd6cebf011e3a971a00e8a72188b9e"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Thu Jun 06 04:48:51 2024 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Thu Jun 06 04:50:37 2024 +0200"
      },
      "message": "Bazel: Disable bzlmod explicitly in .bazelrc\n\nIn Bazel 7.x release line, the bzlmod feature is activated per default,\nso that we need to disable it. See this issue for more details: [1].\n\n[1] https://github.com/bazelbuild/bazel/issues/18958\n\nChange-Id: Id81a1f40392b740146e344d01d96a37f7eabf7e7\n"
    },
    {
      "commit": "f45c596896cd6cebf011e3a971a00e8a72188b9e",
      "tree": "b43f38d5c6572ad8cb08a3f9fc4c7e6ce147ed7e",
      "parents": [
        "2e4362bfd000147eb090354bd2defff0945dcd5e"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Thu Jun 06 04:08:31 2024 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Thu Jun 06 04:50:06 2024 +0200"
      },
      "message": "Bazel: Fix standalone build\n\nUpdate Bazel to the latest release 7.2.0rc3, and update bazlets to the\nlatest version.\n\nAlso upgrade python interpreter to python3.\n\nChange-Id: I228aa6e760fe2b9a9f0af4a340eda9d36befedd4\n"
    },
    {
      "commit": "2e4362bfd000147eb090354bd2defff0945dcd5e",
      "tree": "f51dacefce9d604671740ee4af6d78cd6d9566d2",
      "parents": [
        "b27cf3ea820eec2ddd22d217fc839261692ccdb0"
      ],
      "author": {
        "name": "Ivan Nikolchev",
        "email": "ivan.nikolchev@bonial.com",
        "time": "Sun Apr 14 18:07:43 2024 +0200"
      },
      "committer": {
        "name": "Ivan Nikolchev",
        "email": "ivan.nikolchev@bonial.com",
        "time": "Thu May 23 01:33:08 2024 +0200"
      },
      "message": "Add Cognito OAuth provider\n\nThis adds OAuth provider for AWS Cognito[1].\nThis was tested against a Cognito instance and authentication worked as\nexpected.\n\n1. https://aws.amazon.com/cognito/\n\nChange-Id: Ieb1d014d5d2c40910641c8080a020ab980d997b4\n"
    },
    {
      "commit": "b27cf3ea820eec2ddd22d217fc839261692ccdb0",
      "tree": "80704fcc0368c0f125bffef04fe810af14b4cf85",
      "parents": [
        "1b3cc407cb2571d08601ab852e6e01f82d27160f"
      ],
      "author": {
        "name": "Tobias Urdin",
        "email": "tobias.urdin@gmail.com",
        "time": "Fri Sep 29 08:40:08 2023 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Fri Sep 29 14:46:03 2023 +0200"
      },
      "message": "Add Authentik OAuth provider\n\nThis adds a OAuth provider for Authentik [1].\n\nThis adds a configuration option named link-to-existing-gerrit-accounts\nthat can be set to true to migrate to this provider from existing\nLDAP accounts by linking them with externalIDs instead of trying\nto create new accounts.\n\n[1] https://goauthentik.io\n\nChange-Id: Ic5c46320267fc6cc5416370382c7387666ce8466\n"
    },
    {
      "commit": "1b3cc407cb2571d08601ab852e6e01f82d27160f",
      "tree": "86e60732bc6c4b770776a1dde285b76698f6d4e7",
      "parents": [
        "8d467e99457466c71eb0ca9e661dd433f03a0123"
      ],
      "author": {
        "name": "Joakim Plate",
        "email": "joakim.plate@rt-labs.com",
        "time": "Wed Jun 21 16:33:41 2023 +0200"
      },
      "committer": {
        "name": "Joakim Plate",
        "email": "joakim.plate@rt-labs.com",
        "time": "Wed Jun 21 18:20:42 2023 +0200"
      },
      "message": "Add support for Auth0 OAuth2/OIDC provider\n\nhttps://auth0.com/docs/authenticate/protocols/oauth\n\nChange-Id: I1549abda1e94fba82b2d81713ae37b8cdf264643\n"
    },
    {
      "commit": "8d467e99457466c71eb0ca9e661dd433f03a0123",
      "tree": "5cc339dd797854a4cd86ba22173174338ec34f18",
      "parents": [
        "4bae1d7acc87f7dc1deca3813638bbc07ed5747f"
      ],
      "author": {
        "name": "David Ostrovsky",
        "email": "david@ostrovsky.org",
        "time": "Sun Apr 30 11:04:29 2023 +0200"
      },
      "committer": {
        "name": "David Ostrovsky",
        "email": "david.ostrovsky@gmail.com",
        "time": "Sun May 07 07:56:22 2023 +0000"
      },
      "message": "Keycloak OAuth2 provider: adapt endpoint URL to Quarkus runtime\n\nStarting from Keycloak release v17, the runtime was migrated to Quarkus.\nAs the consequence, the \"/auth\" prefix was removed from the default\ncontext path. Romove the \"/auth\" prefix from endpoint URLs and mention\nin the documentation how to restore previous behaviour for backwards\ncompatibility with legacy Keycloak releases.\n\n[1]: https://www.keycloak.org/migration/migrating-to-quarkus\n\nChange-Id: I8eef636b8104b6112b44692061621968f9ce6b15\n"
    },
    {
      "commit": "4bae1d7acc87f7dc1deca3813638bbc07ed5747f",
      "tree": "90a3a3039fc24806f48a56c97919860bbc20d259",
      "parents": [
        "024c1d9e625b783b2d2cde6c2882188aeda68736"
      ],
      "author": {
        "name": "Thomas Gerbet",
        "email": "thomas.gerbet@enalean.com",
        "time": "Thu Mar 30 14:30:37 2023 +0200"
      },
      "committer": {
        "name": "Thomas Gerbet",
        "email": "thomas.gerbet@enalean.com",
        "time": "Tue May 02 18:50:47 2023 +0200"
      },
      "message": "Add support for Tuleap OAuth2/OIDC provider\n\nTuleap instances can provide an OIDC server: https://docs.tuleap.org/user-guide/oauth2.html\n\nChange-Id: I1625b4cfa5b885257743ac2447fb795a478d86d0\n"
    }
  ],
  "next": "024c1d9e625b783b2d2cde6c2882188aeda68736"
}
