Skip to content

Commit 9936d40

Browse files
committed
CDAP-21256 : Support preserving client credentials when deleting an OAuth provider
1 parent 156cb17 commit 9936d40

3 files changed

Lines changed: 37 additions & 15 deletions

File tree

cdap-app-templates/cdap-etl/cdap-data-pipeline-base/src/main/java/io/cdap/cdap/datapipeline/oauth/OAuthStore.java

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -159,17 +159,20 @@ public Optional<OAuthProvider> getProvider(String name) throws OAuthStoreExcepti
159159
/**
160160
* Remove an OAuth provider.
161161
*
162-
* @param name name of {@link OAuthProvider} to read
163-
* @throws OAuthStoreException if the read fails
162+
* @param name name of {@link OAuthProvider} to delete
163+
* @param preserveClientCredentials whether to preserve existing secrets in secure store
164+
* @throws OAuthStoreException if the delete fails
164165
*/
165-
public void deleteProvider(String name) throws OAuthStoreException {
166-
// Delete associated Client Credentials with given provider.
167-
try {
168-
secureStoreManager.delete(NamespaceId.SYSTEM.getNamespace(), getClientCredsKey(name));
169-
} catch (Exception e) {
170-
// If key is not found, then we can safely delete provider. For any other exception, throw it.
171-
if (!e.getClass().getName().contains("NotFoundException")) {
172-
throw new OAuthStoreException("Failed to delete client credential from OAuth provider secure storage", e);
166+
public void deleteProvider(String name, boolean preserveClientCredentials) throws OAuthStoreException {
167+
// Delete associated Client Credentials with given provider if not preserved.
168+
if (!preserveClientCredentials) {
169+
try {
170+
secureStoreManager.delete(NamespaceId.SYSTEM.getNamespace(), getClientCredsKey(name));
171+
} catch (Exception e) {
172+
// If key is not found, then we can safely delete provider. For any other exception, throw it.
173+
if (!e.getClass().getName().contains("NotFoundException")) {
174+
throw new OAuthStoreException("Failed to delete client credential from OAuth provider secure storage", e);
175+
}
173176
}
174177
}
175178

cdap-app-templates/cdap-etl/cdap-data-pipeline-base/src/main/java/io/cdap/cdap/datapipeline/service/OAuthHandler.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,12 @@ public void putOAuthProvider(HttpServiceRequest request, HttpServiceResponder re
161161
@DELETE
162162
@Path(API_VERSION + "/oauth/provider/{provider}")
163163
public void deleteOAuthProvider(HttpServiceRequest request, HttpServiceResponder responder,
164-
@PathParam("provider") String oauthProvider) {
164+
@PathParam("provider") String oauthProvider,
165+
@QueryParam("preserve_client_credentials") @DefaultValue("false")
166+
boolean preserveClientCredentials) {
165167
try {
166168
try {
167-
oauthStore.deleteProvider(oauthProvider);
169+
oauthStore.deleteProvider(oauthProvider, preserveClientCredentials);
168170
responder.sendStatus(HttpURLConnection.HTTP_OK);
169171
} catch (NullPointerException e) {
170172
throw new OAuthServiceException(HttpURLConnection.HTTP_BAD_REQUEST, "Invalid provider: " + e.getMessage(), e);

cdap-app-templates/cdap-etl/cdap-data-pipeline-base/src/test/java/io/cdap/cdap/datapipeline/OAuthStoreTest.java

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,27 @@ public void testDeleteProvider() throws Exception {
138138

139139
doNothing().when(mockTable).delete(any());
140140

141-
oauthStore.deleteProvider(PROVIDER_NAME);
141+
oauthStore.deleteProvider(PROVIDER_NAME, false);
142142
verify(mockSecureStoreManager, times(1)).delete(any(), any());
143143
}
144144

145+
@Test
146+
public void testDeleteProviderPreserveCredentials() throws Exception {
147+
doAnswer(invocation -> {
148+
TxRunnable runnable = invocation.getArgument(0);
149+
StructuredTableContext mockContext = mock(StructuredTableContext.class);
150+
when(mockContext.getTable(any())).thenReturn(mockTable);
151+
runnable.run(mockContext);
152+
return null;
153+
}).when(mockTransactionRunner).run(any(TxRunnable.class));
154+
155+
doNothing().when(mockTable).delete(any());
156+
157+
oauthStore.deleteProvider(PROVIDER_NAME, true);
158+
verify(mockSecureStoreManager, times(0)).delete(any(), any());
159+
verify(mockTable, times(1)).delete(any());
160+
}
161+
145162
@Test
146163
public void testDeleteProviderWhenSecureKeyNotFound() throws Exception {
147164
class NotFoundException extends Exception {
@@ -161,7 +178,7 @@ public NotFoundException(String message) {
161178

162179
// CASE 1 : When Secure keys not found, the provider should be deleted.
163180
doThrow(new NotFoundException("Keys not found.")).when(mockSecureStoreManager).delete(any(), any());
164-
oauthStore.deleteProvider(PROVIDER_NAME);
181+
oauthStore.deleteProvider(PROVIDER_NAME, false);
165182
verify(mockSecureStoreManager, times(1)).delete(any(), any());
166183
verify(mockTable, times(1)).delete(any());
167184

@@ -170,7 +187,7 @@ public NotFoundException(String message) {
170187
org.mockito.Mockito.clearInvocations(mockTable);
171188
doThrow(new Exception("Unable to delete secure key")).when(mockSecureStoreManager).delete(any(), any());
172189
try {
173-
oauthStore.deleteProvider(PROVIDER_NAME);
190+
oauthStore.deleteProvider(PROVIDER_NAME, false);
174191
} catch (Exception e) {
175192
assertEquals(e.getClass(), OAuthStoreException.class);
176193
}

0 commit comments

Comments
 (0)