Skip to content

fix(auth): fix remaining nullability in UserAuthorizer and Builder - #14158

Merged
lqiu96 merged 10 commits into
mainfrom
fix_auth_user_authorizer_nullability
Aug 21, 2026
Merged

fix(auth): fix remaining nullability in UserAuthorizer and Builder#14158
lqiu96 merged 10 commits into
mainfrom
fix_auth_user_authorizer_nullability

Conversation

@lqiu96

@lqiu96 lqiu96 commented Aug 20, 2026

Copy link
Copy Markdown
Member

Fix remaining nullability annotations, builder defaults, and safe token storage in UserAuthorizer.

  • Make UserAuthorizer.Builder fields @Nullable so unconfigured fields default to null before build() resolves defaults.
  • Enforce non-null parameters across all UserAuthorizer.Builder setters.
  • In UserAuthorizer.storeCredentials, safely guard expiration time checking to avoid NullPointerException when credentials.getAccessToken() is null.
  • Update TokenResponseWithConfig to mark clientSecret as @Nullable for public OAuth clients, and mark refreshToken return type as @Nullable.
  • Add unit tests in UserAuthorizerTest covering toBuilder(), builder defaults, TokenResponseWithConfig, and storeCredentials with null access token.

@lqiu96
lqiu96 requested review from a team as code owners August 20, 2026 22:09

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces nullability annotations, adds non-null preconditions to several builder methods in UserAuthorizer, fixes a typo, and prevents a potential NullPointerException when storing credentials with a null expiration time. It also adds corresponding unit tests. The review feedback identifies a regression in setPKCEProvider where the newly added non-null precondition prevents unsetting or disabling PKCE, and suggests restoring the nullable behavior.

Comment on lines 804 to +840
@@ -836,8 +837,7 @@ public URI getTokenServerUri() {
*
* @return The refresh token, or null if not granted.
*/
@Nullable
public String getRefreshToken() {
public @Nullable String getRefreshToken() {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Turns out Oauth2Utils#validateOptionalString can return null if it doesn't exist. So these two fields use it and it can be null

Comment on lines +782 to +786
this.clientId = Preconditions.checkNotNull(builder.clientId);
this.clientSecret = builder.clientSecret;
this.accessToken = builder.accessToken;
this.httpTransportFactory = builder.httpTransportFactory;
this.tokenServerUri = builder.tokenServerUri;
this.accessToken = Preconditions.checkNotNull(builder.accessToken);
this.httpTransportFactory = Preconditions.checkNotNull(builder.httpTransportFactory);
this.tokenServerUri = Preconditions.checkNotNull(builder.tokenServerUri);

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these are passed in from UserAuthorizer which enforces them to be non-null

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TokenResponseWithConfig#Builder's setters are all package-private and internal usages of this ensures that clientId, accessToken, httpTransportFactory, and tokenServerUri are non-null (default value is created)

@lqiu96
lqiu96 requested a review from whowes August 20, 2026 23:17
@lqiu96

lqiu96 commented Aug 21, 2026

Copy link
Copy Markdown
Member Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates UserAuthorizer by adding @Nullable annotations, fixing typos, preventing integer overflow in expiration calculations, and introducing new unit tests. The reviewer identified a critical issue: omitting expiration_time_millis when storing credentials with a null access token will cause a NullPointerException or validation failure during loading, as the loading logic now unboxes this value into a primitive long. To resolve this, the reviewer suggests making expiration_time_millis optional during retrieval and expanding the test suite to verify that credentials with a null access token can be successfully loaded back.

Map<String, Object> detail = (Map<String, Object>) rawDetail;
String clientId = OAuth2Utils.validateString(detail, FIELD_CLIENT_ID, JSON_PARSE_ERROR);
if (clientId == null || clientId.length() == 0) {
if (clientId.isEmpty()) {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OAuth2Utils.validateString ensures that it's non-null

Comment on lines +431 to +433
if (expiresBy != null) {
tokenStateJson.put("expiration_time_millis", expiresBy.getTime());
}

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can't ensure that expiresBy is non-null because accessToken may null here

@lqiu96
lqiu96 merged commit a51bb8d into main Aug 21, 2026
316 checks passed
@lqiu96
lqiu96 deleted the fix_auth_user_authorizer_nullability branch August 21, 2026 20:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants