Skip to content

Commit d3f73ac

Browse files
authored
Convert operator privilege license object to LicensedFeature (#79407) (#79476)
* Convert operator privilege license object to LicensedFeature (#79407) This commit moves the operator privilege license checks to use the new LicensedFeature class. The XPackLicenseState.Feature enum is also removed because it has no more uses. * checkstyle
1 parent 8c31de6 commit d3f73ac

File tree

8 files changed

+29
-73
lines changed

8 files changed

+29
-73
lines changed

x-pack/plugin/core/src/main/java/org/elasticsearch/license/XPackLicenseState.java

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import java.util.Collections;
2020
import java.util.LinkedHashMap;
2121
import java.util.List;
22-
import java.util.Locale;
2322
import java.util.Map;
2423
import java.util.Objects;
2524
import java.util.concurrent.ConcurrentHashMap;
@@ -35,31 +34,6 @@
3534
*/
3635
public class XPackLicenseState {
3736

38-
/**
39-
* A licensed feature.
40-
*
41-
* Each value defines the licensed state necessary for the feature to be allowed.
42-
*/
43-
public enum Feature {
44-
45-
OPERATOR_PRIVILEGES(OperationMode.ENTERPRISE, true);
46-
47-
// NOTE: this is temporary. The Feature enum will go away in favor of LicensedFeature.
48-
// Embedding the feature instance here is a stopgap to allow smaller initial PR,
49-
// followed by PRs to convert the current consumers of the license state.
50-
final LicensedFeature.Momentary feature;
51-
52-
Feature(OperationMode minimumOperationMode, boolean needsActive) {
53-
assert minimumOperationMode.compareTo(OperationMode.BASIC) > 0: minimumOperationMode.toString();
54-
String name = name().toLowerCase(Locale.ROOT);
55-
if (needsActive) {
56-
this.feature = LicensedFeature.momentary(name, name, minimumOperationMode);
57-
} else {
58-
this.feature = LicensedFeature.momentaryLenient(name, name, minimumOperationMode);
59-
}
60-
}
61-
}
62-
6337
/** Messages for each feature which are printed when the license expires. */
6438
static final Map<String, String[]> EXPIRATION_MESSAGES;
6539
static {
@@ -443,11 +417,6 @@ public String statusDescription() {
443417
return executeAgainstStatus(status -> (status.active ? "active" : "expired") + ' ' + status.mode.description() + " license");
444418
}
445419

446-
@Deprecated
447-
public boolean checkFeature(Feature feature) {
448-
return feature.feature.check(this);
449-
}
450-
451420
void featureUsed(LicensedFeature feature) {
452421
checkExpiry();
453422
usage.put(new FeatureUsage(feature, null), epochMillisProvider.getAsLong());
@@ -475,16 +444,6 @@ void cleanupUsageTracking() {
475444
});
476445
}
477446

478-
/**
479-
* Checks whether the given feature is allowed by the current license.
480-
* <p>
481-
* This method should only be used when serializing whether a feature is allowed for telemetry.
482-
*/
483-
@Deprecated
484-
public boolean isAllowed(Feature feature) {
485-
return isAllowed(feature.feature);
486-
}
487-
488447
// Package protected: Only allowed to be called by LicensedFeature
489448
boolean isAllowed(LicensedFeature feature) {
490449
return isAllowedByLicense(feature.getMinimumOperationMode(), feature.isNeedsActive());

x-pack/plugin/core/src/test/java/org/elasticsearch/license/TestUtils.java

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@
1414
import org.elasticsearch.common.settings.Settings;
1515
import org.elasticsearch.common.time.DateFormatter;
1616
import org.elasticsearch.common.time.DateMathParser;
17-
import org.elasticsearch.xcontent.ToXContent;
18-
import org.elasticsearch.xcontent.XContentBuilder;
19-
import org.elasticsearch.xcontent.XContentFactory;
20-
import org.elasticsearch.xcontent.XContentType;
2117
import org.elasticsearch.core.TimeValue;
2218
import org.elasticsearch.license.licensor.LicenseSigner;
2319
import org.elasticsearch.protocol.xpack.license.LicensesStatus;
2420
import org.elasticsearch.protocol.xpack.license.PutLicenseResponse;
21+
import org.elasticsearch.xcontent.ToXContent;
22+
import org.elasticsearch.xcontent.XContentBuilder;
23+
import org.elasticsearch.xcontent.XContentFactory;
24+
import org.elasticsearch.xcontent.XContentType;
2525
import org.hamcrest.MatcherAssert;
2626
import org.junit.Assert;
2727

@@ -40,15 +40,13 @@
4040
import static com.carrotsearch.randomizedtesting.RandomizedTest.randomBoolean;
4141
import static com.carrotsearch.randomizedtesting.RandomizedTest.randomInt;
4242
import static org.apache.lucene.util.LuceneTestCase.createTempFile;
43-
import static org.elasticsearch.xcontent.XContentFactory.jsonBuilder;
4443
import static org.elasticsearch.test.ESTestCase.randomAlphaOfLength;
4544
import static org.elasticsearch.test.ESTestCase.randomFrom;
4645
import static org.elasticsearch.test.ESTestCase.randomIntBetween;
46+
import static org.elasticsearch.xcontent.XContentFactory.jsonBuilder;
4747
import static org.hamcrest.core.IsEqual.equalTo;
4848
import static org.junit.Assert.assertThat;
49-
import static org.mockito.Matchers.any;
5049
import static org.mockito.Mockito.mock;
51-
import static org.mockito.Mockito.when;
5250

5351
public class TestUtils {
5452

@@ -405,12 +403,6 @@ public static void putLicense(Metadata.Builder builder, License license) {
405403
}
406404

407405
public static MockLicenseState newMockLicenceState() {
408-
MockLicenseState mock = mock(MockLicenseState.class);
409-
// These are deprecated methods, but we haven't replaced all usage of them yet
410-
// By calling the real methods, we force everything through a small number of mockable methods like
411-
// XPackLicenseState.isAllowed(LicensedFeature)
412-
when(mock.isAllowed(any(XPackLicenseState.Feature.class))).thenCallRealMethod();
413-
when(mock.checkFeature(any(XPackLicenseState.Feature.class))).thenCallRealMethod();
414-
return mock;
406+
return mock(MockLicenseState.class);
415407
}
416408
}

x-pack/plugin/repository-encrypted/src/internalClusterTest/java/org/elasticsearch/repositories/encrypted/EncryptedRepositorySecretIntegTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import org.elasticsearch.core.TimeValue;
2121
import org.elasticsearch.license.License;
2222
import org.elasticsearch.license.LicenseService;
23-
import org.elasticsearch.license.XPackLicenseState;
23+
import org.elasticsearch.license.MockLicenseState;
2424
import org.elasticsearch.plugins.Plugin;
2525
import org.elasticsearch.repositories.RepositoriesService;
2626
import org.elasticsearch.repositories.RepositoryData;
@@ -316,7 +316,7 @@ public void testLicenseComplianceSnapshotAndRestore() throws Exception {
316316
RepositoriesService.class
317317
).repository(repositoryName);
318318
encryptedRepository.licenseStateSupplier = () -> {
319-
XPackLicenseState mockLicenseState = mock(XPackLicenseState.class);
319+
MockLicenseState mockLicenseState = mock(MockLicenseState.class);
320320
when(mockLicenseState.isAllowed(anyObject())).thenReturn(false);
321321
return mockLicenseState;
322322
};

x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/Security.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,9 @@ public class Security extends Plugin implements SystemIndexPlugin, IngestPlugin,
387387
public static final LicensedFeature.Persistent CUSTOM_ROLE_PROVIDERS_FEATURE =
388388
LicensedFeature.persistent(null, "security-roles-provider", License.OperationMode.PLATINUM);
389389

390+
public static final LicensedFeature.Momentary OPERATOR_PRIVILEGES_FEATURE =
391+
LicensedFeature.momentary(null, "operator-privileges", License.OperationMode.ENTERPRISE);
392+
390393
private static final Logger logger = LogManager.getLogger(Security.class);
391394

392395
public static final SystemIndexDescriptor SECURITY_MAIN_INDEX_DESCRIPTOR = getSecurityMainIndexDescriptor();

x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/SecurityFeatureSet.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public void usage(ActionListener<XPackFeatureSet.Usage> listener) {
9696
Map<String, Object> anonymousUsage = singletonMap("enabled", AnonymousUser.isAnonymousEnabled(settings));
9797
Map<String, Object> fips140Usage = fips140Usage(settings);
9898
Map<String, Object> operatorPrivilegesUsage = org.elasticsearch.core.Map.of(
99-
"available", licenseState.isAllowed(XPackLicenseState.Feature.OPERATOR_PRIVILEGES),
99+
"available", Security.OPERATOR_PRIVILEGES_FEATURE.checkWithoutTracking(licenseState),
100100
"enabled", OperatorPrivileges.OPERATOR_PRIVILEGES_ENABLED.get(settings)
101101
);
102102

x-pack/plugin/security/src/main/java/org/elasticsearch/xpack/security/operator/OperatorPrivileges.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.elasticsearch.xpack.core.security.authc.Authentication;
1919
import org.elasticsearch.xpack.core.security.authc.AuthenticationField;
2020
import org.elasticsearch.xpack.core.security.user.User;
21+
import org.elasticsearch.xpack.security.Security;
2122

2223
public class OperatorPrivileges {
2324

@@ -110,7 +111,7 @@ public void maybeInterceptRequest(ThreadContext threadContext, TransportRequest
110111
}
111112

112113
private boolean shouldProcess() {
113-
return licenseState.checkFeature(XPackLicenseState.Feature.OPERATOR_PRIVILEGES);
114+
return Security.OPERATOR_PRIVILEGES_FEATURE.check(licenseState);
114115
}
115116
}
116117

x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/SecurityFeatureSetTests.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@
1313
import org.elasticsearch.common.io.stream.BytesStreamOutput;
1414
import org.elasticsearch.common.io.stream.StreamInput;
1515
import org.elasticsearch.common.settings.Settings;
16+
import org.elasticsearch.license.MockLicenseState;
17+
import org.elasticsearch.test.ESTestCase;
18+
import org.elasticsearch.test.VersionUtils;
1619
import org.elasticsearch.xcontent.ToXContent;
1720
import org.elasticsearch.xcontent.XContentBuilder;
1821
import org.elasticsearch.xcontent.XContentFactory;
19-
import org.elasticsearch.license.XPackLicenseState;
20-
import org.elasticsearch.test.ESTestCase;
21-
import org.elasticsearch.test.VersionUtils;
2222
import org.elasticsearch.xpack.core.XPackFeatureSet;
2323
import org.elasticsearch.xpack.core.XPackField;
2424
import org.elasticsearch.xpack.core.XPackSettings;
@@ -51,7 +51,7 @@
5151
public class SecurityFeatureSetTests extends ESTestCase {
5252

5353
private Settings settings;
54-
private XPackLicenseState licenseState;
54+
private MockLicenseState licenseState;
5555
private Realms realms;
5656
private IPFilter ipFilter;
5757
private CompositeRolesStore rolesStore;
@@ -60,7 +60,7 @@ public class SecurityFeatureSetTests extends ESTestCase {
6060
@Before
6161
public void init() throws Exception {
6262
settings = Settings.builder().put("path.home", createTempDir()).build();
63-
licenseState = mock(XPackLicenseState.class);
63+
licenseState = mock(MockLicenseState.class);
6464
realms = mock(Realms.class);
6565
ipFilter = mock(IPFilter.class);
6666
rolesStore = mock(CompositeRolesStore.class);
@@ -90,7 +90,7 @@ public void testUsage() throws Exception {
9090
final boolean operatorPrivilegesAvailable = randomBoolean();
9191
final boolean enabled = explicitlyDisabled == false && randomBoolean();
9292
when(licenseState.isSecurityEnabled()).thenReturn(enabled);
93-
when(licenseState.isAllowed(XPackLicenseState.Feature.OPERATOR_PRIVILEGES)).thenReturn(operatorPrivilegesAvailable);
93+
when(licenseState.isAllowed(Security.OPERATOR_PRIVILEGES_FEATURE)).thenReturn(operatorPrivilegesAvailable);
9494

9595
Settings.Builder settings = Settings.builder().put(this.settings);
9696

x-pack/plugin/security/src/test/java/org/elasticsearch/xpack/security/operator/OperatorPrivilegesTests.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
import org.elasticsearch.common.logging.Loggers;
1616
import org.elasticsearch.common.settings.Settings;
1717
import org.elasticsearch.common.util.concurrent.ThreadContext;
18-
import org.elasticsearch.license.XPackLicenseState;
18+
import org.elasticsearch.license.MockLicenseState;
1919
import org.elasticsearch.test.ESTestCase;
2020
import org.elasticsearch.test.MockLogAppender;
2121
import org.elasticsearch.transport.TransportRequest;
@@ -26,6 +26,7 @@
2626
import org.elasticsearch.xpack.core.security.user.User;
2727
import org.elasticsearch.xpack.core.security.user.XPackSecurityUser;
2828
import org.elasticsearch.xpack.core.security.user.XPackUser;
29+
import org.elasticsearch.xpack.security.Security;
2930
import org.elasticsearch.xpack.security.operator.OperatorPrivileges.DefaultOperatorPrivilegesService;
3031
import org.elasticsearch.xpack.security.operator.OperatorPrivileges.OperatorPrivilegesService;
3132
import org.junit.Before;
@@ -44,14 +45,14 @@
4445

4546
public class OperatorPrivilegesTests extends ESTestCase {
4647

47-
private XPackLicenseState xPackLicenseState;
48+
private MockLicenseState xPackLicenseState;
4849
private FileOperatorUsersStore fileOperatorUsersStore;
4950
private OperatorOnlyRegistry operatorOnlyRegistry;
5051
private OperatorPrivilegesService operatorPrivilegesService;
5152

5253
@Before
5354
public void init() {
54-
xPackLicenseState = mock(XPackLicenseState.class);
55+
xPackLicenseState = mock(MockLicenseState.class);
5556
fileOperatorUsersStore = mock(FileOperatorUsersStore.class);
5657
operatorOnlyRegistry = mock(OperatorOnlyRegistry.class);
5758
operatorPrivilegesService = new DefaultOperatorPrivilegesService(xPackLicenseState, fileOperatorUsersStore, operatorOnlyRegistry);
@@ -61,7 +62,7 @@ public void testWillNotProcessWhenFeatureIsDisabledOrLicenseDoesNotSupport() {
6162
final Settings settings = Settings.builder()
6263
.put("xpack.security.operator_privileges.enabled", randomBoolean())
6364
.build();
64-
when(xPackLicenseState.checkFeature(XPackLicenseState.Feature.OPERATOR_PRIVILEGES)).thenReturn(false);
65+
when(xPackLicenseState.isAllowed(Security.OPERATOR_PRIVILEGES_FEATURE)).thenReturn(false);
6566
final ThreadContext threadContext = new ThreadContext(settings);
6667

6768
operatorPrivilegesService.maybeMarkOperatorUser(mock(Authentication.class), threadContext);
@@ -77,7 +78,7 @@ public void testMarkOperatorUser() throws IllegalAccessException {
7778
final Settings settings = Settings.builder()
7879
.put("xpack.security.operator_privileges.enabled", true)
7980
.build();
80-
when(xPackLicenseState.checkFeature(XPackLicenseState.Feature.OPERATOR_PRIVILEGES)).thenReturn(true);
81+
when(xPackLicenseState.isAllowed(Security.OPERATOR_PRIVILEGES_FEATURE)).thenReturn(true);
8182
final Authentication operatorAuth = mock(Authentication.class);
8283
final Authentication nonOperatorAuth = mock(Authentication.class);
8384
final User operatorUser = new User("operator_user");
@@ -142,7 +143,7 @@ public void testCheck() {
142143
final Settings settings = Settings.builder()
143144
.put("xpack.security.operator_privileges.enabled", true)
144145
.build();
145-
when(xPackLicenseState.checkFeature(XPackLicenseState.Feature.OPERATOR_PRIVILEGES)).thenReturn(true);
146+
when(xPackLicenseState.isAllowed(Security.OPERATOR_PRIVILEGES_FEATURE)).thenReturn(true);
146147

147148
final String operatorAction = "cluster:operator_only/action";
148149
final String nonOperatorAction = "cluster:non_operator/action";
@@ -167,7 +168,7 @@ public void testCheck() {
167168
}
168169

169170
public void testCheckWillPassForInternalUsers() {
170-
when(xPackLicenseState.checkFeature(XPackLicenseState.Feature.OPERATOR_PRIVILEGES)).thenReturn(true);
171+
when(xPackLicenseState.isAllowed(Security.OPERATOR_PRIVILEGES_FEATURE)).thenReturn(true);
171172
final Authentication internalAuth = mock(Authentication.class);
172173
when(internalAuth.getUser()).thenReturn(
173174
randomFrom(SystemUser.INSTANCE, XPackUser.INSTANCE, XPackSecurityUser.INSTANCE, AsyncSearchUser.INSTANCE));
@@ -178,7 +179,7 @@ public void testCheckWillPassForInternalUsers() {
178179

179180
public void testMaybeInterceptRequest() throws IllegalAccessException {
180181
final boolean licensed = randomBoolean();
181-
when(xPackLicenseState.checkFeature(XPackLicenseState.Feature.OPERATOR_PRIVILEGES)).thenReturn(licensed);
182+
when(xPackLicenseState.isAllowed(Security.OPERATOR_PRIVILEGES_FEATURE)).thenReturn(licensed);
182183

183184
final Logger logger = LogManager.getLogger(OperatorPrivileges.class);
184185
final MockLogAppender appender = new MockLogAppender();

0 commit comments

Comments
 (0)