Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
Expand All @@ -35,31 +34,6 @@
*/
public class XPackLicenseState {

/**
* A licensed feature.
*
* Each value defines the licensed state necessary for the feature to be allowed.
*/
public enum Feature {

OPERATOR_PRIVILEGES(OperationMode.ENTERPRISE, true);

// NOTE: this is temporary. The Feature enum will go away in favor of LicensedFeature.
// Embedding the feature instance here is a stopgap to allow smaller initial PR,
// followed by PRs to convert the current consumers of the license state.
final LicensedFeature.Momentary feature;

Feature(OperationMode minimumOperationMode, boolean needsActive) {
assert minimumOperationMode.compareTo(OperationMode.BASIC) > 0: minimumOperationMode.toString();
String name = name().toLowerCase(Locale.ROOT);
if (needsActive) {
this.feature = LicensedFeature.momentary(name, name, minimumOperationMode);
} else {
this.feature = LicensedFeature.momentaryLenient(name, name, minimumOperationMode);
}
}
}

/** Messages for each feature which are printed when the license expires. */
static final Map<String, String[]> EXPIRATION_MESSAGES;
static {
Expand Down Expand Up @@ -428,11 +402,6 @@ public String statusDescription() {
return executeAgainstStatus(status -> (status.active ? "active" : "expired") + ' ' + status.mode.description() + " license");
}

@Deprecated
public boolean checkFeature(Feature feature) {
return feature.feature.check(this);
}

void featureUsed(LicensedFeature feature) {
checkExpiry();
usage.put(new FeatureUsage(feature, null), epochMillisProvider.getAsLong());
Expand Down Expand Up @@ -460,16 +429,6 @@ void cleanupUsageTracking() {
});
}

/**
* Checks whether the given feature is allowed by the current license.
* <p>
* This method should only be used when serializing whether a feature is allowed for telemetry.
*/
@Deprecated
public boolean isAllowed(Feature feature) {
return isAllowed(feature.feature);
}

// Package protected: Only allowed to be called by LicensedFeature
boolean isAllowed(LicensedFeature feature) {
return isAllowedByLicense(feature.getMinimumOperationMode(), feature.isNeedsActive());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.time.DateFormatter;
import org.elasticsearch.common.time.DateMathParser;
import org.elasticsearch.xcontent.ToXContent;
import org.elasticsearch.xcontent.XContentBuilder;
import org.elasticsearch.xcontent.XContentFactory;
import org.elasticsearch.xcontent.XContentType;
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.license.licensor.LicenseSigner;
import org.elasticsearch.protocol.xpack.license.LicensesStatus;
import org.elasticsearch.protocol.xpack.license.PutLicenseResponse;
import org.elasticsearch.xcontent.ToXContent;
import org.elasticsearch.xcontent.XContentBuilder;
import org.elasticsearch.xcontent.XContentFactory;
import org.elasticsearch.xcontent.XContentType;
import org.hamcrest.MatcherAssert;
import org.junit.Assert;

Expand All @@ -40,15 +40,13 @@
import static com.carrotsearch.randomizedtesting.RandomizedTest.randomBoolean;
import static com.carrotsearch.randomizedtesting.RandomizedTest.randomInt;
import static org.apache.lucene.util.LuceneTestCase.createTempFile;
import static org.elasticsearch.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.test.ESTestCase.randomAlphaOfLength;
import static org.elasticsearch.test.ESTestCase.randomFrom;
import static org.elasticsearch.test.ESTestCase.randomIntBetween;
import static org.elasticsearch.xcontent.XContentFactory.jsonBuilder;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class TestUtils {

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

public static MockLicenseState newMockLicenceState() {
MockLicenseState mock = mock(MockLicenseState.class);
// These are deprecated methods, but we haven't replaced all usage of them yet
// By calling the real methods, we force everything through a small number of mockable methods like
// XPackLicenseState.isAllowed(LicensedFeature)
when(mock.isAllowed(any(XPackLicenseState.Feature.class))).thenCallRealMethod();
when(mock.checkFeature(any(XPackLicenseState.Feature.class))).thenCallRealMethod();
return mock;
return mock(MockLicenseState.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import org.elasticsearch.core.TimeValue;
import org.elasticsearch.license.License;
import org.elasticsearch.license.LicenseService;
import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.license.MockLicenseState;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.repositories.RepositoriesService;
import org.elasticsearch.repositories.RepositoryData;
Expand Down Expand Up @@ -316,7 +316,7 @@ public void testLicenseComplianceSnapshotAndRestore() throws Exception {
RepositoriesService.class
).repository(repositoryName);
encryptedRepository.licenseStateSupplier = () -> {
XPackLicenseState mockLicenseState = mock(XPackLicenseState.class);
MockLicenseState mockLicenseState = mock(MockLicenseState.class);
when(mockLicenseState.isAllowed(anyObject())).thenReturn(false);
return mockLicenseState;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,9 @@ public class Security extends Plugin implements SystemIndexPlugin, IngestPlugin,
public static final LicensedFeature.Persistent CUSTOM_ROLE_PROVIDERS_FEATURE =
LicensedFeature.persistent(null, "security-roles-provider", License.OperationMode.PLATINUM);

public static final LicensedFeature.Momentary OPERATOR_PRIVILEGES_FEATURE =
LicensedFeature.momentary(null, "operator-privileges", License.OperationMode.ENTERPRISE);

private static final Logger logger = LogManager.getLogger(Security.class);

public static final SystemIndexDescriptor SECURITY_MAIN_INDEX_DESCRIPTOR = getSecurityMainIndexDescriptor();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ protected void masterOperation(Task task, XPackUsageRequest request, ClusterStat
Map<String, Object> anonymousUsage = singletonMap("enabled", AnonymousUser.isAnonymousEnabled(settings));
Map<String, Object> fips140Usage = fips140Usage(settings);
Map<String, Object> operatorPrivilegesUsage = Map.of(
"available", licenseState.isAllowed(XPackLicenseState.Feature.OPERATOR_PRIVILEGES),
"available", Security.OPERATOR_PRIVILEGES_FEATURE.checkWithoutTracking(licenseState),
"enabled", OperatorPrivileges.OPERATOR_PRIVILEGES_ENABLED.get(settings)
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.AuthenticationField;
import org.elasticsearch.xpack.core.security.user.User;
import org.elasticsearch.xpack.security.Security;

public class OperatorPrivileges {

Expand Down Expand Up @@ -110,7 +111,7 @@ public void maybeInterceptRequest(ThreadContext threadContext, TransportRequest
}

private boolean shouldProcess() {
return licenseState.checkFeature(XPackLicenseState.Feature.OPERATOR_PRIVILEGES);
return Security.OPERATOR_PRIVILEGES_FEATURE.check(licenseState);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
import org.elasticsearch.common.collect.MapBuilder;
import org.elasticsearch.common.io.stream.BytesStreamOutput;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.license.MockLicenseState;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.transport.TransportService;
import org.elasticsearch.xcontent.ToXContent;
import org.elasticsearch.xcontent.XContentBuilder;
import org.elasticsearch.xcontent.XContentFactory;
import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.transport.TransportService;
import org.elasticsearch.xpack.core.XPackFeatureSet;
import org.elasticsearch.xpack.core.XPackField;
import org.elasticsearch.xpack.core.XPackSettings;
Expand Down Expand Up @@ -51,7 +51,7 @@
public class SecurityInfoTransportActionTests extends ESTestCase {

private Settings settings;
private XPackLicenseState licenseState;
private MockLicenseState licenseState;
private Realms realms;
private IPFilter ipFilter;
private CompositeRolesStore rolesStore;
Expand All @@ -61,7 +61,7 @@ public class SecurityInfoTransportActionTests extends ESTestCase {
@Before
public void init() throws Exception {
settings = Settings.builder().put("path.home", createTempDir()).build();
licenseState = mock(XPackLicenseState.class);
licenseState = mock(MockLicenseState.class);
realms = mock(Realms.class);
ipFilter = mock(IPFilter.class);
rolesStore = mock(CompositeRolesStore.class);
Expand Down Expand Up @@ -91,7 +91,7 @@ public void testUsage() throws Exception {
final boolean explicitlyDisabled = randomBoolean();
final boolean enabled = explicitlyDisabled == false;
final boolean operatorPrivilegesAvailable = randomBoolean();
when(licenseState.isAllowed(XPackLicenseState.Feature.OPERATOR_PRIVILEGES)).thenReturn(operatorPrivilegesAvailable);
when(licenseState.isAllowed(Security.OPERATOR_PRIVILEGES_FEATURE)).thenReturn(operatorPrivilegesAvailable);

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.license.MockLicenseState;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.MockLogAppender;
import org.elasticsearch.transport.TransportRequest;
Expand All @@ -26,6 +26,7 @@
import org.elasticsearch.xpack.core.security.user.User;
import org.elasticsearch.xpack.core.security.user.XPackSecurityUser;
import org.elasticsearch.xpack.core.security.user.XPackUser;
import org.elasticsearch.xpack.security.Security;
import org.elasticsearch.xpack.security.operator.OperatorPrivileges.DefaultOperatorPrivilegesService;
import org.elasticsearch.xpack.security.operator.OperatorPrivileges.OperatorPrivilegesService;
import org.junit.Before;
Expand All @@ -44,14 +45,14 @@

public class OperatorPrivilegesTests extends ESTestCase {

private XPackLicenseState xPackLicenseState;
private MockLicenseState xPackLicenseState;
private FileOperatorUsersStore fileOperatorUsersStore;
private OperatorOnlyRegistry operatorOnlyRegistry;
private OperatorPrivilegesService operatorPrivilegesService;

@Before
public void init() {
xPackLicenseState = mock(XPackLicenseState.class);
xPackLicenseState = mock(MockLicenseState.class);
fileOperatorUsersStore = mock(FileOperatorUsersStore.class);
operatorOnlyRegistry = mock(OperatorOnlyRegistry.class);
operatorPrivilegesService = new DefaultOperatorPrivilegesService(xPackLicenseState, fileOperatorUsersStore, operatorOnlyRegistry);
Expand All @@ -61,7 +62,7 @@ public void testWillNotProcessWhenFeatureIsDisabledOrLicenseDoesNotSupport() {
final Settings settings = Settings.builder()
.put("xpack.security.operator_privileges.enabled", randomBoolean())
.build();
when(xPackLicenseState.checkFeature(XPackLicenseState.Feature.OPERATOR_PRIVILEGES)).thenReturn(false);
when(xPackLicenseState.isAllowed(Security.OPERATOR_PRIVILEGES_FEATURE)).thenReturn(false);
final ThreadContext threadContext = new ThreadContext(settings);

operatorPrivilegesService.maybeMarkOperatorUser(mock(Authentication.class), threadContext);
Expand All @@ -77,7 +78,7 @@ public void testMarkOperatorUser() throws IllegalAccessException {
final Settings settings = Settings.builder()
.put("xpack.security.operator_privileges.enabled", true)
.build();
when(xPackLicenseState.checkFeature(XPackLicenseState.Feature.OPERATOR_PRIVILEGES)).thenReturn(true);
when(xPackLicenseState.isAllowed(Security.OPERATOR_PRIVILEGES_FEATURE)).thenReturn(true);
final Authentication operatorAuth = mock(Authentication.class);
final Authentication nonOperatorAuth = mock(Authentication.class);
final User operatorUser = new User("operator_user");
Expand Down Expand Up @@ -142,7 +143,7 @@ public void testCheck() {
final Settings settings = Settings.builder()
.put("xpack.security.operator_privileges.enabled", true)
.build();
when(xPackLicenseState.checkFeature(XPackLicenseState.Feature.OPERATOR_PRIVILEGES)).thenReturn(true);
when(xPackLicenseState.isAllowed(Security.OPERATOR_PRIVILEGES_FEATURE)).thenReturn(true);

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

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

public void testMaybeInterceptRequest() throws IllegalAccessException {
final boolean licensed = randomBoolean();
when(xPackLicenseState.checkFeature(XPackLicenseState.Feature.OPERATOR_PRIVILEGES)).thenReturn(licensed);
when(xPackLicenseState.isAllowed(Security.OPERATOR_PRIVILEGES_FEATURE)).thenReturn(licensed);

final Logger logger = LogManager.getLogger(OperatorPrivileges.class);
final MockLogAppender appender = new MockLogAppender();
Expand Down