|
51 | 51 | import org.elasticsearch.index.get.GetResult;
|
52 | 52 | import org.elasticsearch.index.seqno.SequenceNumbers;
|
53 | 53 | import org.elasticsearch.index.shard.ShardId;
|
| 54 | +import org.elasticsearch.license.License; |
54 | 55 | import org.elasticsearch.license.MockLicenseState;
|
55 | 56 | import org.elasticsearch.license.XPackLicenseState;
|
56 | 57 | import org.elasticsearch.license.XPackLicenseState.Feature;
|
@@ -220,16 +221,23 @@ public void init() throws Exception {
|
220 | 221 | .build();
|
221 | 222 | MockLicenseState licenseState = mock(MockLicenseState.class);
|
222 | 223 | when(licenseState.isAllowed(Security.ALL_REALMS_FEATURE)).thenReturn(true);
|
| 224 | + when(licenseState.isAllowed(Security.STANDARD_REALMS_FEATURE)).thenReturn(true); |
223 | 225 | when(licenseState.checkFeature(Feature.SECURITY_TOKEN_SERVICE)).thenReturn(true);
|
224 | 226 | when(licenseState.copyCurrentLicenseState()).thenReturn(licenseState);
|
225 | 227 | when(licenseState.checkFeature(Feature.SECURITY_AUDITING)).thenReturn(true);
|
| 228 | + when(licenseState.getOperationMode()).thenReturn(randomFrom(License.OperationMode.ENTERPRISE, License.OperationMode.PLATINUM)); |
| 229 | + |
226 | 230 | ReservedRealm reservedRealm = mock(ReservedRealm.class);
|
227 | 231 | when(reservedRealm.type()).thenReturn("reserved");
|
228 | 232 | when(reservedRealm.name()).thenReturn("reserved_realm");
|
229 | 233 | realms = spy(new TestRealms(Settings.EMPTY, TestEnvironment.newEnvironment(settings),
|
230 | 234 | Map.of(FileRealmSettings.TYPE, config -> mock(FileRealm.class), NativeRealmSettings.TYPE, config -> mock(NativeRealm.class)),
|
231 | 235 | licenseState, threadContext, reservedRealm, Arrays.asList(firstRealm, secondRealm),
|
232 |
| - Collections.singletonList(firstRealm))); |
| 236 | + Arrays.asList(firstRealm))); |
| 237 | + |
| 238 | + // Needed because this is calculated in the constructor, which means the override doesn't get called correctly |
| 239 | + realms.recomputeActiveRealms(); |
| 240 | + assertThat(realms.asList(), contains(firstRealm, secondRealm)); |
233 | 241 |
|
234 | 242 | auditTrail = mock(AuditTrail.class);
|
235 | 243 | auditTrailService = new AuditTrailService(Collections.singletonList(auditTrail), licenseState);
|
@@ -388,7 +396,10 @@ public void testAuthenticateBothSupportSecondSucceeds() throws Exception {
|
388 | 396 | }, this::logAndFail));
|
389 | 397 | assertTrue(completed.get());
|
390 | 398 | verify(auditTrail).authenticationFailed(reqId.get(), firstRealm.name(), token, "_action", transportRequest);
|
391 |
| - verify(realms).asList(); |
| 399 | + verify(realms, atLeastOnce()).recomputeActiveRealms(); |
| 400 | + verify(realms, atLeastOnce()).calculateLicensedRealms(any(XPackLicenseState.class)); |
| 401 | + verify(realms, atLeastOnce()).asList(); |
| 402 | + // ^^ We don't care how many times these methods are called, we just check it here so that we can verify no more interactions below. |
392 | 403 | verifyNoMoreInteractions(realms);
|
393 | 404 | }
|
394 | 405 |
|
@@ -447,9 +458,8 @@ public void testAuthenticateSmartRealmOrdering() {
|
447 | 458 |
|
448 | 459 | verify(auditTrail).authenticationFailed(reqId.get(), firstRealm.name(), token, "_action", transportRequest);
|
449 | 460 | verify(firstRealm, times(2)).name(); // used above one time
|
450 |
| - verify(firstRealm, atLeastOnce()).type(); |
451 |
| - verify(secondRealm, Mockito.atLeast(3)).name(); // also used in license tracking |
452 |
| - verify(secondRealm, Mockito.atLeast(3)).type(); // used to create realm ref, and license tracking |
| 461 | + verify(secondRealm, Mockito.atLeast(2)).name(); // also used in license tracking |
| 462 | + verify(secondRealm, Mockito.atLeast(2)).type(); // used to create realm ref, and license tracking |
453 | 463 | verify(firstRealm, times(2)).token(threadContext);
|
454 | 464 | verify(secondRealm, times(2)).token(threadContext);
|
455 | 465 | verify(firstRealm).supports(token);
|
@@ -573,9 +583,8 @@ public void testAuthenticateSmartRealmOrderingDisabled() {
|
573 | 583 | }, this::logAndFail));
|
574 | 584 | verify(auditTrail, times(2)).authenticationFailed(reqId.get(), firstRealm.name(), token, "_action", transportRequest);
|
575 | 585 | verify(firstRealm, times(3)).name(); // used above one time
|
576 |
| - verify(firstRealm, atLeastOnce()).type(); |
577 |
| - verify(secondRealm, Mockito.atLeast(3)).name(); |
578 |
| - verify(secondRealm, Mockito.atLeast(3)).type(); // used to create realm ref |
| 586 | + verify(secondRealm, Mockito.atLeast(2)).name(); |
| 587 | + verify(secondRealm, Mockito.atLeast(2)).type(); // used to create realm ref |
579 | 588 | verify(firstRealm, times(2)).token(threadContext);
|
580 | 589 | verify(secondRealm, times(2)).token(threadContext);
|
581 | 590 | verify(firstRealm, times(2)).supports(token);
|
@@ -638,10 +647,7 @@ public void testAuthenticateCached() throws Exception {
|
638 | 647 | assertThat(result.v1(), is(authentication));
|
639 | 648 | assertThat(result.v1().getAuthenticationType(), is(AuthenticationType.REALM));
|
640 | 649 | verifyZeroInteractions(auditTrail);
|
641 |
| - verify(firstRealm, atLeastOnce()).type(); |
642 |
| - verify(secondRealm, atLeastOnce()).type(); |
643 |
| - verify(secondRealm, atLeastOnce()).name(); // This realm is license-tracked, which uses the name |
644 |
| - verifyNoMoreInteractions(firstRealm, secondRealm); |
| 650 | + verifyZeroInteractions(firstRealm, secondRealm); |
645 | 651 | verifyZeroInteractions(operatorPrivilegesService);
|
646 | 652 | }
|
647 | 653 |
|
@@ -920,8 +926,6 @@ public void testAuthenticateTransportContextAndHeader() throws Exception {
|
920 | 926 | verifyZeroInteractions(operatorPrivilegesService);
|
921 | 927 | }, this::logAndFail));
|
922 | 928 | assertTrue(completed.compareAndSet(true, false));
|
923 |
| - verify(firstRealm, atLeastOnce()).type(); |
924 |
| - verify(firstRealm, atLeastOnce()).name(); |
925 | 929 | verifyNoMoreInteractions(firstRealm);
|
926 | 930 | reset(firstRealm);
|
927 | 931 | } finally {
|
@@ -970,8 +974,6 @@ public void testAuthenticateTransportContextAndHeader() throws Exception {
|
970 | 974 | verifyZeroInteractions(operatorPrivilegesService);
|
971 | 975 | }, this::logAndFail));
|
972 | 976 | assertTrue(completed.get());
|
973 |
| - verify(firstRealm, atLeastOnce()).type(); |
974 |
| - verify(firstRealm, atLeastOnce()).name(); |
975 | 977 | verifyNoMoreInteractions(firstRealm);
|
976 | 978 | } finally {
|
977 | 979 | terminate(threadPool2);
|
@@ -2106,12 +2108,40 @@ private static void mockRealmLookupReturnsNull(Realm realm, String username) {
|
2106 | 2108 |
|
2107 | 2109 | static class TestRealms extends Realms {
|
2108 | 2110 |
|
2109 |
| - TestRealms(Settings settings, Environment env, Map<String, Factory> factories, XPackLicenseState licenseState, |
2110 |
| - ThreadContext threadContext, ReservedRealm reservedRealm, List<Realm> realms, List<Realm> internalRealms) |
2111 |
| - throws Exception { |
| 2111 | + private final List<Realm> allRealms; |
| 2112 | + private final List<Realm> internalRealms; |
| 2113 | + |
| 2114 | + TestRealms( |
| 2115 | + Settings settings, |
| 2116 | + Environment env, |
| 2117 | + Map<String, Factory> factories, |
| 2118 | + XPackLicenseState licenseState, |
| 2119 | + ThreadContext threadContext, |
| 2120 | + ReservedRealm reservedRealm, |
| 2121 | + List<Realm> realms, |
| 2122 | + List<Realm> internalRealms |
| 2123 | + ) throws Exception { |
2112 | 2124 | super(settings, env, factories, licenseState, threadContext, reservedRealm);
|
2113 |
| - this.realms = realms; |
2114 |
| - this.standardRealmsOnly = internalRealms; |
| 2125 | + this.allRealms = realms; |
| 2126 | + this.internalRealms = internalRealms; |
| 2127 | + } |
| 2128 | + |
| 2129 | + @Override |
| 2130 | + protected List<Realm> calculateLicensedRealms(XPackLicenseState licenseState) { |
| 2131 | + if (allRealms == null) { |
| 2132 | + // This can happen because the realms are recalculated during construction |
| 2133 | + return super.calculateLicensedRealms(licenseState); |
| 2134 | + } |
| 2135 | + if (Security.STANDARD_REALMS_FEATURE.checkWithoutTracking(licenseState)) { |
| 2136 | + return allRealms; |
| 2137 | + } else { |
| 2138 | + return internalRealms; |
| 2139 | + } |
| 2140 | + } |
| 2141 | + |
| 2142 | + // Make public for testing |
| 2143 | + public void recomputeActiveRealms() { |
| 2144 | + super.recomputeActiveRealms(); |
2115 | 2145 | }
|
2116 | 2146 | }
|
2117 | 2147 |
|
|
0 commit comments