Skip to content
This repository was archived by the owner on May 12, 2026. It is now read-only.

Commit ab21104

Browse files
hiranya911garrettjonesgoogle
authored andcommitted
Providing a method to remove CredentialsChangedListeners (#130)
1 parent 51a5445 commit ab21104

2 files changed

Lines changed: 49 additions & 0 deletions

File tree

oauth2_http/java/com/google/auth/oauth2/OAuth2Credentials.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,19 @@ public final void addChangeListener(CredentialsChangedListener listener) {
227227
}
228228
}
229229

230+
/**
231+
* Removes a listener that was added previously.
232+
*
233+
* @param listener The listener to be removed.
234+
*/
235+
public final void removeChangeListener(CredentialsChangedListener listener) {
236+
synchronized(lock) {
237+
if (changeListeners != null) {
238+
changeListeners.remove(listener);
239+
}
240+
}
241+
}
242+
230243
/**
231244
* Return the remaining time the current access token will be valid, or null if there is no
232245
* token or expiry information. Must be called under lock.

oauth2_http/javatests/com/google/auth/oauth2/OAuth2CredentialsTest.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,42 @@ public void addChangeListener_notifiesOnRefresh() throws IOException {
143143
assertEquals(2, listener.callCount);
144144
}
145145

146+
@Test
147+
public void removeChangeListener_unregisters_observer() throws IOException {
148+
final String accessToken1 = "1/MkSJoj1xsli0AccessToken_NKPY2";
149+
final String accessToken2 = "2/MkSJoj1xsli0AccessToken_NKPY2";
150+
MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
151+
transportFactory.transport.addClient(CLIENT_ID, CLIENT_SECRET);
152+
transportFactory.transport.addRefreshToken(REFRESH_TOKEN, accessToken1);
153+
OAuth2Credentials userCredentials = UserCredentials.newBuilder()
154+
.setClientId(CLIENT_ID)
155+
.setClientSecret(CLIENT_SECRET)
156+
.setRefreshToken(REFRESH_TOKEN)
157+
.setHttpTransportFactory(transportFactory)
158+
.build();
159+
// Use a fixed clock so tokens don't expire
160+
userCredentials.clock = new TestClock();
161+
TestChangeListener listener = new TestChangeListener();
162+
userCredentials.addChangeListener(listener);
163+
assertEquals(0, listener.callCount);
164+
165+
// Get a first token
166+
userCredentials.getRequestMetadata(CALL_URI);
167+
assertEquals(1, listener.callCount);
168+
169+
// Change server to a different token and refresh
170+
transportFactory.transport.addRefreshToken(REFRESH_TOKEN, accessToken2);
171+
// Refresh to force getting next token
172+
userCredentials.refresh();
173+
assertEquals(2, listener.callCount);
174+
175+
// Remove the listener and refresh the credential again
176+
userCredentials.removeChangeListener(listener);
177+
transportFactory.transport.addRefreshToken(REFRESH_TOKEN, accessToken2);
178+
userCredentials.refresh();
179+
assertEquals(2, listener.callCount);
180+
}
181+
146182
@Test
147183
public void getRequestMetadata_blocking_cachesExpiringToken() throws IOException {
148184
final String accessToken1 = "1/MkSJoj1xsli0AccessToken_NKPY2";

0 commit comments

Comments
 (0)