Skip to content

Commit ae4c0ec

Browse files
authored
Add operations to create and delete SAML provider configs. (#420)
This adds operations to create and delete SAML provider configs.
1 parent 51fdc91 commit ae4c0ec

File tree

10 files changed

+567
-46
lines changed

10 files changed

+567
-46
lines changed

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

Lines changed: 104 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -939,13 +939,15 @@ protected String execute() throws FirebaseAuthException {
939939
}
940940

941941
/**
942-
* Creates a new provider OIDC Auth config with the attributes contained in the specified {@link
943-
* OidcProviderConfig.CreateRequest}.
942+
* Creates a new OIDC Auth provider config with the attributes contained in the specified
943+
* {@link OidcProviderConfig.CreateRequest}.
944944
*
945945
* @param request A non-null {@link OidcProviderConfig.CreateRequest} instance.
946946
* @return An {@link OidcProviderConfig} instance corresponding to the newly created provider
947947
* config.
948948
* @throws NullPointerException if the provided request is null.
949+
* @throws IllegalArgumentException If the provider ID string is null or empty, or is not
950+
* prefixed with 'oidc.'.
949951
* @throws FirebaseAuthException if an error occurs while creating the provider config.
950952
*/
951953
public OidcProviderConfig createOidcProviderConfig(
@@ -961,6 +963,8 @@ public OidcProviderConfig createOidcProviderConfig(
961963
* instance corresponding to the newly created provider config. If an error occurs while
962964
* creating the provider config, the future throws a {@link FirebaseAuthException}.
963965
* @throws NullPointerException if the provided request is null.
966+
* @throws IllegalArgumentException If the provider ID string is null or empty, or is not
967+
* prefixed with 'oidc.'.
964968
*/
965969
public ApiFuture<OidcProviderConfig> createOidcProviderConfigAsync(
966970
@NonNull OidcProviderConfig.CreateRequest request) {
@@ -971,6 +975,7 @@ public ApiFuture<OidcProviderConfig> createOidcProviderConfigAsync(
971975
createOidcProviderConfigOp(final OidcProviderConfig.CreateRequest request) {
972976
checkNotDestroyed();
973977
checkNotNull(request, "Create request must not be null.");
978+
OidcProviderConfig.checkOidcProviderId(request.getProviderId());
974979
final FirebaseUserManager userManager = getUserManager();
975980
return new CallableOperation<OidcProviderConfig, FirebaseAuthException>() {
976981
@Override
@@ -1025,7 +1030,8 @@ protected OidcProviderConfig execute() throws FirebaseAuthException {
10251030
*
10261031
* @param providerId A provider ID string.
10271032
* @return An {@link OidcProviderConfig} instance.
1028-
* @throws IllegalArgumentException If the provider ID string is null or empty.
1033+
* @throws IllegalArgumentException If the provider ID string is null or empty, or is not prefixed
1034+
* with 'oidc'.
10291035
* @throws FirebaseAuthException If an error occurs while retrieving the provider config.
10301036
*/
10311037
public OidcProviderConfig getOidcProviderConfig(@NonNull String providerId)
@@ -1042,7 +1048,8 @@ public OidcProviderConfig getOidcProviderConfig(@NonNull String providerId)
10421048
* {@link OidcProviderConfig} instance. If an error occurs while retrieving the provider
10431049
* config or if the specified provider ID does not exist, the future throws a
10441050
* {@link FirebaseAuthException}.
1045-
* @throws IllegalArgumentException If the provider ID string is null or empty.
1051+
* @throws IllegalArgumentException If the provider ID string is null or empty, or is not
1052+
* prefixed with 'oidc.'.
10461053
*/
10471054
public ApiFuture<OidcProviderConfig> getOidcProviderConfigAsync(@NonNull String providerId) {
10481055
return getOidcProviderConfigOp(providerId).callAsync(firebaseApp);
@@ -1051,7 +1058,7 @@ public ApiFuture<OidcProviderConfig> getOidcProviderConfigAsync(@NonNull String
10511058
private CallableOperation<OidcProviderConfig, FirebaseAuthException>
10521059
getOidcProviderConfigOp(final String providerId) {
10531060
checkNotDestroyed();
1054-
checkArgument(!Strings.isNullOrEmpty(providerId), "Provider ID must not be null or empty.");
1061+
OidcProviderConfig.checkOidcProviderId(providerId);
10551062
final FirebaseUserManager userManager = getUserManager();
10561063
return new CallableOperation<OidcProviderConfig, FirebaseAuthException>() {
10571064
@Override
@@ -1152,7 +1159,8 @@ protected ListProviderConfigsPage<OidcProviderConfig> execute()
11521159
* Deletes the OIDC Auth provider config identified by the specified provider ID.
11531160
*
11541161
* @param providerId A provider ID string.
1155-
* @throws IllegalArgumentException If the provider ID string is null or empty.
1162+
* @throws IllegalArgumentException If the provider ID string is null or empty, or is not prefixed
1163+
* with 'oidc'.
11561164
* @throws FirebaseAuthException If an error occurs while deleting the provider config.
11571165
*/
11581166
public void deleteOidcProviderConfig(@NonNull String providerId) throws FirebaseAuthException {
@@ -1166,7 +1174,8 @@ public void deleteOidcProviderConfig(@NonNull String providerId) throws Firebase
11661174
* @return An {@code ApiFuture} which will complete successfully when the specified provider
11671175
* config has been deleted. If an error occurs while deleting the provider config, the future
11681176
* throws a {@link FirebaseAuthException}.
1169-
* @throws IllegalArgumentException If the provider ID string is null or empty.
1177+
* @throws IllegalArgumentException If the provider ID string is null or empty, or is not prefixed
1178+
* with "oidc.".
11701179
*/
11711180
public ApiFuture<Void> deleteOidcProviderConfigAsync(String providerId) {
11721181
return deleteOidcProviderConfigOp(providerId).callAsync(firebaseApp);
@@ -1175,7 +1184,7 @@ public ApiFuture<Void> deleteOidcProviderConfigAsync(String providerId) {
11751184
private CallableOperation<Void, FirebaseAuthException> deleteOidcProviderConfigOp(
11761185
final String providerId) {
11771186
checkNotDestroyed();
1178-
checkArgument(!Strings.isNullOrEmpty(providerId), "Provider ID must not be null or empty.");
1187+
OidcProviderConfig.checkOidcProviderId(providerId);
11791188
final FirebaseUserManager userManager = getUserManager();
11801189
return new CallableOperation<Void, FirebaseAuthException>() {
11811190
@Override
@@ -1186,6 +1195,93 @@ protected Void execute() throws FirebaseAuthException {
11861195
};
11871196
}
11881197

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

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

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,8 @@ Tenant createTenant(Tenant.CreateRequest request) throws FirebaseAuthException {
252252

253253
Tenant updateTenant(Tenant.UpdateRequest request) throws FirebaseAuthException {
254254
Map<String, Object> properties = request.getProperties();
255+
// TODO(micahstairs): Move this check so that argument validation happens outside the
256+
// CallableOperation.
255257
checkArgument(!properties.isEmpty(), "tenant update must have at least one property set");
256258
GenericUrl url = new GenericUrl(tenantMgtBaseUrl + getTenantUrlSuffix(request.getTenantId()));
257259
url.put("updateMask", generateMask(properties));
@@ -318,15 +320,22 @@ String getEmailActionLink(EmailLinkType type, String email,
318320
OidcProviderConfig createOidcProviderConfig(
319321
OidcProviderConfig.CreateRequest request) throws FirebaseAuthException {
320322
GenericUrl url = new GenericUrl(idpConfigMgtBaseUrl + "/oauthIdpConfigs");
321-
String providerId = request.getProviderId();
322-
checkArgument(!Strings.isNullOrEmpty(providerId), "Provider ID must not be null or empty.");
323-
url.set("oauthIdpConfigId", providerId);
323+
url.set("oauthIdpConfigId", request.getProviderId());
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+
url.set("inboundSamlConfigId", request.getProviderId());
331+
return sendRequest("POST", url, request.getProperties(), SamlProviderConfig.class);
332+
}
333+
327334
OidcProviderConfig updateOidcProviderConfig(OidcProviderConfig.UpdateRequest request)
328335
throws FirebaseAuthException {
329336
Map<String, Object> properties = request.getProperties();
337+
// TODO(micahstairs): Move this check so that argument validation happens outside the
338+
// CallableOperation.
330339
checkArgument(!properties.isEmpty(),
331340
"Provider config update must have at least one property set.");
332341
GenericUrl url =
@@ -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/main/java/com/google/firebase/auth/OidcProviderConfig.java

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ public UpdateRequest updateRequest() {
5454
return new UpdateRequest(getProviderId());
5555
}
5656

57+
static void checkOidcProviderId(String providerId) {
58+
checkArgument(!Strings.isNullOrEmpty(providerId), "Provider ID must not be null or empty.");
59+
checkArgument(providerId.startsWith("oidc."),
60+
"Invalid OIDC provider ID (must be prefixed with 'oidc.'): " + providerId);
61+
}
62+
5763
/**
5864
* A specification class for creating a new OIDC Auth provider.
5965
*
@@ -71,6 +77,19 @@ public static final class CreateRequest extends AbstractCreateRequest<CreateRequ
7177
*/
7278
public CreateRequest() { }
7379

80+
/**
81+
* Sets the ID for the new provider.
82+
*
83+
* @param providerId A non-null, non-empty provider ID string.
84+
* @throws IllegalArgumentException If the provider ID is null or empty, or is not prefixed with
85+
* 'oidc.'.
86+
*/
87+
@Override
88+
public CreateRequest setProviderId(String providerId) {
89+
checkOidcProviderId(providerId);
90+
return super.setProviderId(providerId);
91+
}
92+
7493
/**
7594
* Sets the client ID for the new provider.
7695
*
@@ -100,10 +119,6 @@ public CreateRequest setIssuer(String issuer) {
100119
CreateRequest getThis() {
101120
return this;
102121
}
103-
104-
void assertValidProviderIdFormat(String providerId) {
105-
checkArgument(providerId.startsWith("oidc."), "Invalid OIDC provider ID: " + providerId);
106-
}
107122
}
108123

109124
/**
@@ -129,7 +144,7 @@ public static final class UpdateRequest extends AbstractUpdateRequest<UpdateRequ
129144
*/
130145
public UpdateRequest(String providerId) {
131146
super(providerId);
132-
checkArgument(providerId.startsWith("oidc."), "Invalid OIDC provider ID: " + providerId);
147+
checkOidcProviderId(providerId);
133148
}
134149

135150
/**

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

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -71,17 +71,7 @@ public abstract static class AbstractCreateRequest<T extends AbstractCreateReque
7171
final Map<String,Object> properties = new HashMap<>();
7272
String providerId;
7373

74-
/**
75-
* Sets the ID for the new provider.
76-
*
77-
* @param providerId A non-null, non-empty provider ID string.
78-
* @throws IllegalArgumentException If the provider ID is null or empty, or if the format is
79-
* invalid.
80-
*/
81-
public T setProviderId(String providerId) {
82-
checkArgument(
83-
!Strings.isNullOrEmpty(providerId), "Provider ID name must not be null or empty.");
84-
assertValidProviderIdFormat(providerId);
74+
T setProviderId(String providerId) {
8575
this.providerId = providerId;
8676
return getThis();
8777
}
@@ -117,8 +107,6 @@ Map<String, Object> getProperties() {
117107
}
118108

119109
abstract T getThis();
120-
121-
abstract void assertValidProviderIdFormat(String providerId);
122110
}
123111

124112
/**

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

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ public String getCallbackUrl() {
7171
return (String) spConfig.get("callbackUri");
7272
}
7373

74+
static void checkSamlProviderId(String providerId) {
75+
checkArgument(!Strings.isNullOrEmpty(providerId), "Provider ID must not be null or empty.");
76+
checkArgument(providerId.startsWith("saml."),
77+
"Invalid SAML provider ID (must be prefixed with 'saml.'): " + providerId);
78+
}
79+
7480
private static List<Object> ensureNestedList(Map<String, Object> outerMap, String id) {
7581
List<Object> list = (List<Object>) outerMap.get(id);
7682
if (list == null) {
@@ -106,6 +112,19 @@ public static final class CreateRequest extends AbstractCreateRequest<CreateRequ
106112
*/
107113
public CreateRequest() { }
108114

115+
/**
116+
* Sets the ID for the new provider.
117+
*
118+
* @param providerId A non-null, non-empty provider ID string.
119+
* @throws IllegalArgumentException If the provider ID is null or empty, or is not prefixed with
120+
* 'saml.'.
121+
*/
122+
@Override
123+
public CreateRequest setProviderId(String providerId) {
124+
checkSamlProviderId(providerId);
125+
return super.setProviderId(providerId);
126+
}
127+
109128
/**
110129
* Sets the IDP entity ID for the new provider.
111130
*
@@ -181,9 +200,5 @@ public CreateRequest setCallbackUrl(String callbackUrl) {
181200
CreateRequest getThis() {
182201
return this;
183202
}
184-
185-
void assertValidProviderIdFormat(String providerId) {
186-
checkArgument(providerId.startsWith("saml."), "Invalid SAML provider ID: " + providerId);
187-
}
188203
}
189204
}

0 commit comments

Comments
 (0)