Skip to content

Commit 8533d1e

Browse files
aji-ajuclaude
andauthored
fix(auth): treat empty allowedEmailRegistrationDomains as no restrictions (#27178) (#27179)
Add isEmpty() guard so that an empty domain list does not block all OAuth self-signups. The JSON schema defaults this field to [], which previously meant "no restrictions" but started blocking every signup after the domain validation was introduced in #25391. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent af7ffe7 commit 8533d1e

2 files changed

Lines changed: 116 additions & 0 deletions

File tree

openmetadata-service/src/main/java/org/openmetadata/service/security/AuthenticationCodeFlowHandler.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -930,6 +930,7 @@ private User getOrCreateOidcUser(String userName, String email, Map<String, Obje
930930
// Validate email domain against allowed registration domains
931931
Set<String> allowedDomains = authorizerConfiguration.getAllowedEmailRegistrationDomains();
932932
if (allowedDomains != null
933+
&& !allowedDomains.isEmpty()
933934
&& !allowedDomains.contains("all")
934935
&& !allowedDomains.contains(domain)) {
935936
LOG.warn(

openmetadata-service/src/test/java/org/openmetadata/service/security/AuthenticationCodeFlowHandlerTest.java

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import java.time.Instant;
5858
import java.util.Date;
5959
import java.util.HashMap;
60+
import java.util.LinkedHashSet;
6061
import java.util.List;
6162
import java.util.Map;
6263
import java.util.Set;
@@ -1234,6 +1235,120 @@ void getOrCreateOidcUserUpdatesExistingUserFromAdminAndTeamClaims() throws Excep
12341235
}
12351236
}
12361237

1238+
@Test
1239+
void getOrCreateOidcUserAllowsSignupWhenAllowedDomainsEmpty() throws Exception {
1240+
AuthenticationCodeFlowHandler handler = newHandler();
1241+
AuthenticationConfiguration authConfig = new AuthenticationConfiguration();
1242+
authConfig.setEnableSelfSignup(true);
1243+
setField(handler, "authenticationConfiguration", authConfig);
1244+
AuthorizerConfiguration authorizer = authorizerConfiguration(Set.of());
1245+
authorizer.setAllowedEmailRegistrationDomains(new LinkedHashSet<>());
1246+
setField(handler, "authorizerConfiguration", authorizer);
1247+
1248+
try (MockedStatic<Entity> entity = mockStatic(Entity.class);
1249+
MockedStatic<UserUtil> userUtil = mockStatic(UserUtil.class)) {
1250+
entity
1251+
.when(
1252+
() ->
1253+
Entity.getEntityByName(
1254+
Entity.USER, "gmail-user", "id,roles,teams", Include.NON_DELETED))
1255+
.thenThrow(EntityNotFoundException.byName("gmail-user"));
1256+
User draftUser = new User();
1257+
userUtil
1258+
.when(() -> UserUtil.user("gmail-user", "gmail.com", "gmail-user"))
1259+
.thenReturn(draftUser);
1260+
userUtil.when(() -> UserUtil.assignTeamsFromClaim(draftUser, List.of())).thenReturn(false);
1261+
User persistedUser = new User();
1262+
persistedUser.setName("gmail-user");
1263+
userUtil.when(() -> UserUtil.addOrUpdateUser(draftUser)).thenReturn(persistedUser);
1264+
1265+
User user =
1266+
invokePrivate(
1267+
handler,
1268+
"getOrCreateOidcUser",
1269+
new Class<?>[] {String.class, String.class, Map.class},
1270+
"gmail-user",
1271+
"gmail-user@gmail.com",
1272+
Map.of());
1273+
1274+
assertEquals(persistedUser, user);
1275+
}
1276+
}
1277+
1278+
@Test
1279+
void getOrCreateOidcUserBlocksDisallowedDomain() throws Exception {
1280+
AuthenticationCodeFlowHandler handler = newHandler();
1281+
AuthenticationConfiguration authConfig = new AuthenticationConfiguration();
1282+
authConfig.setEnableSelfSignup(true);
1283+
setField(handler, "authenticationConfiguration", authConfig);
1284+
AuthorizerConfiguration authorizer = authorizerConfiguration(Set.of());
1285+
authorizer.setAllowedEmailRegistrationDomains(Set.of("corp.com"));
1286+
setField(handler, "authorizerConfiguration", authorizer);
1287+
1288+
try (MockedStatic<Entity> entity = mockStatic(Entity.class)) {
1289+
entity
1290+
.when(
1291+
() ->
1292+
Entity.getEntityByName(
1293+
Entity.USER, "outside-user", "id,roles,teams", Include.NON_DELETED))
1294+
.thenThrow(EntityNotFoundException.byName("outside-user"));
1295+
1296+
AuthenticationException exception =
1297+
assertThrows(
1298+
AuthenticationException.class,
1299+
() ->
1300+
invokePrivate(
1301+
handler,
1302+
"getOrCreateOidcUser",
1303+
new Class<?>[] {String.class, String.class, Map.class},
1304+
"outside-user",
1305+
"outside-user@gmail.com",
1306+
Map.of()));
1307+
1308+
assertTrue(exception.getMessage().contains("Email domain not allowed"));
1309+
}
1310+
}
1311+
1312+
@Test
1313+
void getOrCreateOidcUserAllowsMatchingDomain() throws Exception {
1314+
AuthenticationCodeFlowHandler handler = newHandler();
1315+
AuthenticationConfiguration authConfig = new AuthenticationConfiguration();
1316+
authConfig.setEnableSelfSignup(true);
1317+
setField(handler, "authenticationConfiguration", authConfig);
1318+
AuthorizerConfiguration authorizer = authorizerConfiguration(Set.of());
1319+
authorizer.setAllowedEmailRegistrationDomains(Set.of("gmail.com"));
1320+
setField(handler, "authorizerConfiguration", authorizer);
1321+
1322+
try (MockedStatic<Entity> entity = mockStatic(Entity.class);
1323+
MockedStatic<UserUtil> userUtil = mockStatic(UserUtil.class)) {
1324+
entity
1325+
.when(
1326+
() ->
1327+
Entity.getEntityByName(
1328+
Entity.USER, "gmail-user", "id,roles,teams", Include.NON_DELETED))
1329+
.thenThrow(EntityNotFoundException.byName("gmail-user"));
1330+
User draftUser = new User();
1331+
userUtil
1332+
.when(() -> UserUtil.user("gmail-user", "gmail.com", "gmail-user"))
1333+
.thenReturn(draftUser);
1334+
userUtil.when(() -> UserUtil.assignTeamsFromClaim(draftUser, List.of())).thenReturn(false);
1335+
User persistedUser = new User();
1336+
persistedUser.setName("gmail-user");
1337+
userUtil.when(() -> UserUtil.addOrUpdateUser(draftUser)).thenReturn(persistedUser);
1338+
1339+
User user =
1340+
invokePrivate(
1341+
handler,
1342+
"getOrCreateOidcUser",
1343+
new Class<?>[] {String.class, String.class, Map.class},
1344+
"gmail-user",
1345+
"gmail-user@gmail.com",
1346+
Map.of());
1347+
1348+
assertEquals(persistedUser, user);
1349+
}
1350+
}
1351+
12371352
@Test
12381353
void handleCallbackReturnsErrorWhenProviderRespondsWithAuthenticationError() throws Exception {
12391354
AuthenticationCodeFlowHandler handler = newHandler();

0 commit comments

Comments
 (0)