Skip to content

Commit 72170c4

Browse files
committed
Add create and delete operations for SAML provider configs.
1 parent d2d0c43 commit 72170c4

File tree

7 files changed

+424
-11
lines changed

7 files changed

+424
-11
lines changed

src/main/java/com/google/firebase/auth/AbstractFirebaseAuth.java

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,6 +1186,86 @@ protected Void execute() throws FirebaseAuthException {
11861186
};
11871187
}
11881188

1189+
/**
1190+
* Creates a new provider SAML Auth config with the attributes contained in the specified {@link
1191+
* SamlProviderConfig.CreateRequest}.
1192+
*
1193+
* @param request A non-null {@link SamlProviderConfig.CreateRequest} instance.
1194+
* @return An {@link SamlProviderConfig} instance corresponding to the newly created provider
1195+
* config.
1196+
* @throws NullPointerException if the provided request is null.
1197+
* @throws FirebaseAuthException if an error occurs while creating the provider config.
1198+
*/
1199+
public SamlProviderConfig createSamlProviderConfig(
1200+
@NonNull SamlProviderConfig.CreateRequest request) throws FirebaseAuthException {
1201+
return createSamlProviderConfigOp(request).call();
1202+
}
1203+
1204+
/**
1205+
* Similar to {@link #createSamlProviderConfig} but performs the operation asynchronously.
1206+
*
1207+
* @param request A non-null {@link SamlProviderConfig.CreateRequest} instance.
1208+
* @return An {@code ApiFuture} which will complete successfully with a {@link SamlProviderConfig}
1209+
* instance corresponding to the newly created provider config. If an error occurs while
1210+
* creating the provider config, the future throws a {@link FirebaseAuthException}.
1211+
* @throws NullPointerException if the provided request is null.
1212+
*/
1213+
public ApiFuture<SamlProviderConfig> createSamlProviderConfigAsync(
1214+
@NonNull SamlProviderConfig.CreateRequest request) {
1215+
return createSamlProviderConfigOp(request).callAsync(firebaseApp);
1216+
}
1217+
1218+
private CallableOperation<SamlProviderConfig, FirebaseAuthException>
1219+
createSamlProviderConfigOp(final SamlProviderConfig.CreateRequest request) {
1220+
checkNotDestroyed();
1221+
checkNotNull(request, "Create request must not be null.");
1222+
final FirebaseUserManager userManager = getUserManager();
1223+
return new CallableOperation<SamlProviderConfig, FirebaseAuthException>() {
1224+
@Override
1225+
protected SamlProviderConfig execute() throws FirebaseAuthException {
1226+
return userManager.createSamlProviderConfig(request);
1227+
}
1228+
};
1229+
}
1230+
1231+
/**
1232+
* Deletes the SAML Auth provider config identified by the specified provider ID.
1233+
*
1234+
* @param providerId A provider ID string.
1235+
* @throws IllegalArgumentException If the provider ID string is null or empty.
1236+
* @throws FirebaseAuthException If an error occurs while deleting the provider config.
1237+
*/
1238+
public void deleteSamlProviderConfig(@NonNull String providerId) throws FirebaseAuthException {
1239+
deleteSamlProviderConfigOp(providerId).call();
1240+
}
1241+
1242+
/**
1243+
* Similar to {@link #deleteSamlProviderConfig} but performs the operation asynchronously.
1244+
*
1245+
* @param providerId A provider ID string.
1246+
* @return An {@code ApiFuture} which will complete successfully when the specified provider
1247+
* config has been deleted. If an error occurs while deleting the provider config, the future
1248+
* throws a {@link FirebaseAuthException}.
1249+
* @throws IllegalArgumentException If the provider ID string is null or empty.
1250+
*/
1251+
public ApiFuture<Void> deleteSamlProviderConfigAsync(String providerId) {
1252+
return deleteSamlProviderConfigOp(providerId).callAsync(firebaseApp);
1253+
}
1254+
1255+
private CallableOperation<Void, FirebaseAuthException> deleteSamlProviderConfigOp(
1256+
final String providerId) {
1257+
checkNotDestroyed();
1258+
checkArgument(!Strings.isNullOrEmpty(providerId), "Provider ID must not be null or empty.");
1259+
final FirebaseUserManager userManager = getUserManager();
1260+
return new CallableOperation<Void, FirebaseAuthException>() {
1261+
@Override
1262+
protected Void execute() throws FirebaseAuthException {
1263+
userManager.deleteSamlProviderConfig(providerId);
1264+
return null;
1265+
}
1266+
};
1267+
}
1268+
11891269
FirebaseApp getFirebaseApp() {
11901270
return this.firebaseApp;
11911271
}

src/main/java/com/google/firebase/auth/FirebaseUserManager.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,15 @@ OidcProviderConfig createOidcProviderConfig(
324324
return sendRequest("POST", url, request.getProperties(), OidcProviderConfig.class);
325325
}
326326

327+
SamlProviderConfig createSamlProviderConfig(
328+
SamlProviderConfig.CreateRequest request) throws FirebaseAuthException {
329+
GenericUrl url = new GenericUrl(idpConfigMgtBaseUrl + "/inboundSamlConfigs");
330+
String providerId = request.getProviderId();
331+
checkArgument(!Strings.isNullOrEmpty(providerId), "Provider ID must not be null or empty.");
332+
url.set("inboundSamlConfigId", providerId);
333+
return sendRequest("POST", url, request.getProperties(), SamlProviderConfig.class);
334+
}
335+
327336
OidcProviderConfig updateOidcProviderConfig(OidcProviderConfig.UpdateRequest request)
328337
throws FirebaseAuthException {
329338
Map<String, Object> properties = request.getProperties();
@@ -365,6 +374,11 @@ void deleteOidcProviderConfig(String providerId) throws FirebaseAuthException {
365374
sendRequest("DELETE", url, null, GenericJson.class);
366375
}
367376

377+
void deleteSamlProviderConfig(String providerId) throws FirebaseAuthException {
378+
GenericUrl url = new GenericUrl(idpConfigMgtBaseUrl + getSamlUrlSuffix(providerId));
379+
sendRequest("DELETE", url, null, GenericJson.class);
380+
}
381+
368382
private static String generateMask(Map<String, Object> properties) {
369383
// This implementation does not currently handle the case of nested properties. This is fine
370384
// since we do not currently generate masks for any properties with nested values. When it
@@ -383,6 +397,11 @@ private static String getOidcUrlSuffix(String providerId) {
383397
return "/oauthIdpConfigs/" + providerId;
384398
}
385399

400+
private static String getSamlUrlSuffix(String providerId) {
401+
checkArgument(!Strings.isNullOrEmpty(providerId), "Provider ID must not be null or empty.");
402+
return "/inboundSamlConfigs/" + providerId;
403+
}
404+
386405
private <T> T post(String path, Object content, Class<T> clazz) throws FirebaseAuthException {
387406
checkArgument(!Strings.isNullOrEmpty(path), "path must not be null or empty");
388407
checkNotNull(content, "content must not be null for POST requests");

src/test/java/com/google/firebase/auth/FirebaseAuthIT.java

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,7 @@ public void testOidcProviderConfigLifecycle() throws Exception {
601601
assertEquals("https://oidc.com/new-issuer", config.getIssuer());
602602

603603
// Delete config provider
604-
auth.deleteOidcProviderConfigAsync(providerId).get();
604+
temporaryProviderConfig.deleteOidcProviderConfig(providerId);
605605
ProviderConfigTestUtils.assertOidcProviderConfigDoesNotExist(auth, providerId);
606606
}
607607

@@ -613,7 +613,7 @@ public void testListOidcProviderConfigs() throws Exception {
613613
for (int i = 0; i < 3; i++) {
614614
String providerId = "oidc.provider-id" + i;
615615
providerIds.add(providerId);
616-
OidcProviderConfig config = temporaryProviderConfig.createOidcProviderConfig(
616+
temporaryProviderConfig.createOidcProviderConfig(
617617
new OidcProviderConfig.CreateRequest()
618618
.setProviderId(providerId)
619619
.setClientId("CLIENT_ID")
@@ -674,6 +674,40 @@ public void onSuccess(ListProviderConfigsPage<OidcProviderConfig> result) {
674674
assertNull(error.get());
675675
}
676676

677+
@Test
678+
public void testSamlProviderConfigLifecycle() throws Exception {
679+
// Create config provider
680+
String providerId = "saml.provider-id";
681+
SamlProviderConfig config = temporaryProviderConfig.createSamlProviderConfig(
682+
new SamlProviderConfig.CreateRequest()
683+
.setProviderId(providerId)
684+
.setDisplayName("DisplayName")
685+
.setEnabled(true)
686+
.setIdpEntityId("IDP_ENTITY_ID")
687+
.setSsoUrl("https://example.com/login")
688+
.addX509Certificate("certificate1")
689+
.addX509Certificate("certificate2")
690+
.setRpEntityId("RP_ENTITY_ID")
691+
.setCallbackUrl("https://projectId.firebaseapp.com/__/auth/handler"));
692+
assertEquals(providerId, config.getProviderId());
693+
assertEquals("DisplayName", config.getDisplayName());
694+
assertTrue(config.isEnabled());
695+
assertEquals("IDP_ENTITY_ID", config.getIdpEntityId());
696+
assertEquals("https://example.com/login", config.getSsoUrl());
697+
assertEquals(ImmutableList.of("certificate1", "certificate2"), config.getX509Certificates());
698+
assertEquals("RP_ENTITY_ID", config.getRpEntityId());
699+
assertEquals("https://projectId.firebaseapp.com/__/auth/handler", config.getCallbackUrl());
700+
701+
// TODO(micahstairs): Once implemented, add tests for getting and updating the SAML provider
702+
// config.
703+
704+
// Delete config provider
705+
temporaryProviderConfig.deleteSamlProviderConfig(providerId);
706+
707+
// TODO(micahstairs): Once the operation to get a SAML config is implemented, add an assertion
708+
// that the SAML provider does not exist.
709+
}
710+
677711
private Map<String, String> parseLinkParameters(String link) throws Exception {
678712
Map<String, String> result = new HashMap<>();
679713
int queryBegin = link.indexOf('?');
@@ -813,7 +847,6 @@ private boolean checkProviderConfig(List<String> providerIds, OidcProviderConfig
813847
return false;
814848
}
815849

816-
817850
private static void assertUserDoesNotExist(AbstractFirebaseAuth firebaseAuth, String uid)
818851
throws Exception {
819852
try {

0 commit comments

Comments
 (0)