Skip to content

Commit

Permalink
Convert token service license object to LicensedFeature (elastic#79284)
Browse files Browse the repository at this point in the history
This commit moves the token service license checks to use the new
LicensedFeature class.
  • Loading branch information
rjernst committed Oct 19, 2021
1 parent 1df96c5 commit 3e09876
Show file tree
Hide file tree
Showing 13 changed files with 62 additions and 178 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,6 @@ public class XPackLicenseState {
* Each value defines the licensed state necessary for the feature to be allowed.
*/
public enum Feature {
SECURITY_AUDITING(OperationMode.GOLD, false),
SECURITY_TOKEN_SERVICE(OperationMode.STANDARD, false),

MACHINE_LEARNING(OperationMode.PLATINUM, true),

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.iterable.Iterables;
import org.elasticsearch.license.License.OperationMode;
import org.elasticsearch.license.XPackLicenseState.Feature;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.core.XPackField;
import org.elasticsearch.xpack.core.XPackSettings;
Expand Down Expand Up @@ -88,122 +87,6 @@ public static OperationMode randomBasicStandardOrGold() {
return randomFrom(BASIC, STANDARD, GOLD);
}

public void testSecurityDefaults() {
Settings settings = Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build();
XPackLicenseState licenseState = new XPackLicenseState(settings, () -> 0);
assertThat(licenseState.isSecurityEnabled(), is(true));
assertThat(licenseState.checkFeature(Feature.SECURITY_AUDITING), is(true));

licenseState = TestUtils.newTestLicenseState();
assertSecurityNotAllowed(licenseState);
}

public void testTransportSslDoesNotAutomaticallyEnableSecurityOnTrialLicense() {
Settings settings = Settings.builder().put(XPackSettings.TRANSPORT_SSL_ENABLED.getKey(), true).build();
final XPackLicenseState licenseState= new XPackLicenseState(settings, () -> 0);
assertSecurityNotAllowed(licenseState);
}

public void testSecurityBasicWithoutExplicitSecurityEnabled() {
XPackLicenseState licenseState = TestUtils.newTestLicenseState();
licenseState.update(BASIC, true, null);

assertThat(licenseState.isSecurityEnabled(), is(false));
assertThat(licenseState.checkFeature(Feature.SECURITY_AUDITING), is(false));
assertThat(licenseState.checkFeature(Feature.SECURITY_TOKEN_SERVICE), is(false));

assertThat(licenseState.isSecurityEnabled(), is(false));
}

public void testSecurityBasicWithExplicitSecurityEnabled() {
final Settings settings = Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build();
XPackLicenseState licenseState = new XPackLicenseState(settings, () -> 0);
licenseState.update(BASIC, true, null);
assertThat(licenseState.isSecurityEnabled(), is(true));
assertThat(licenseState.checkFeature(Feature.SECURITY_AUDITING), is(false));
assertThat(licenseState.checkFeature(Feature.SECURITY_TOKEN_SERVICE), is(false));

assertThat(licenseState.isSecurityEnabled(), is(true));
}

public void testSecurityStandard() {
Settings settings = randomFrom(Settings.EMPTY,
Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build());
XPackLicenseState licenseState = new XPackLicenseState(settings, () -> 0);
licenseState.update(STANDARD, true, null);

assertThat(licenseState.isSecurityEnabled(), is(true));
assertThat(licenseState.checkFeature(Feature.SECURITY_AUDITING), is(false));
assertThat(licenseState.checkFeature(Feature.SECURITY_TOKEN_SERVICE), is(true));
}

public void testSecurityStandardExpired() {
Settings settings = randomFrom(Settings.EMPTY,
Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build());
XPackLicenseState licenseState = new XPackLicenseState(settings, () -> 0);
licenseState.update(STANDARD, false, null);

assertThat(licenseState.isSecurityEnabled(), is(true));
assertThat(licenseState.checkFeature(Feature.SECURITY_AUDITING), is(false));
assertThat(licenseState.checkFeature(Feature.SECURITY_TOKEN_SERVICE), is(true));
}

public void testSecurityGold() {
Settings settings = randomFrom(Settings.EMPTY,
Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build());
XPackLicenseState licenseState = new XPackLicenseState(settings, () -> 0);
licenseState.update(GOLD, true, null);

assertThat(licenseState.isSecurityEnabled(), is(true));
assertThat(licenseState.checkFeature(Feature.SECURITY_AUDITING), is(true));
assertThat(licenseState.checkFeature(Feature.SECURITY_TOKEN_SERVICE), is(true));
}

public void testSecurityGoldExpired() {
Settings settings = randomFrom(Settings.EMPTY,
Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build());
XPackLicenseState licenseState = new XPackLicenseState(settings, () -> 0);
licenseState.update(GOLD, false, null);

assertThat(licenseState.isSecurityEnabled(), is(true));
assertThat(licenseState.checkFeature(Feature.SECURITY_AUDITING), is(true));
assertThat(licenseState.checkFeature(Feature.SECURITY_TOKEN_SERVICE), is(true));
}

public void testSecurityPlatinum() {
Settings settings = randomFrom(Settings.EMPTY,
Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build());
XPackLicenseState licenseState = new XPackLicenseState(settings, () -> 0);
licenseState.update(PLATINUM, true, null);

assertThat(licenseState.isSecurityEnabled(), is(true));
assertThat(licenseState.checkFeature(Feature.SECURITY_AUDITING), is(true));
assertThat(licenseState.checkFeature(Feature.SECURITY_TOKEN_SERVICE), is(true));
}

public void testSecurityPlatinumExpired() {
Settings settings = randomFrom(Settings.EMPTY,
Settings.builder().put(XPackSettings.SECURITY_ENABLED.getKey(), true).build());
XPackLicenseState licenseState = new XPackLicenseState(settings, () -> 0);
licenseState.update(PLATINUM, false, null);

assertThat(licenseState.isSecurityEnabled(), is(true));
assertThat(licenseState.checkFeature(Feature.SECURITY_AUDITING), is(true));
assertThat(licenseState.checkFeature(Feature.SECURITY_TOKEN_SERVICE), is(true));
}

public void testNewTrialDefaultsSecurityOff() {
XPackLicenseState licenseState = TestUtils.newTestLicenseState();
licenseState.update(TRIAL, true, null);

assertThat(licenseState.isSecurityEnabled(), is(false));
assertSecurityNotAllowed(licenseState);
}

private void assertSecurityNotAllowed(XPackLicenseState licenseState) {
assertThat(licenseState.isSecurityEnabled(), is(false));
}

public void testSecurityAckBasicToNotGoldOrStandard() {
OperationMode toMode = randomFrom(OperationMode.values(), mode -> mode != GOLD && mode != STANDARD);
assertAckMessages(XPackField.SECURITY, BASIC, toMode, 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@
import org.elasticsearch.common.util.concurrent.EsExecutors;
import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.common.util.set.Sets;
import org.elasticsearch.xcontent.NamedXContentRegistry;
import org.elasticsearch.xcontent.XContentBuilder;
import org.elasticsearch.env.Environment;
import org.elasticsearch.env.NodeEnvironment;
import org.elasticsearch.http.HttpServerTransport;
Expand Down Expand Up @@ -82,6 +80,8 @@
import org.elasticsearch.transport.TransportRequestHandler;
import org.elasticsearch.transport.nio.NioGroupFactory;
import org.elasticsearch.watcher.ResourceWatcherService;
import org.elasticsearch.xcontent.NamedXContentRegistry;
import org.elasticsearch.xcontent.XContentBuilder;
import org.elasticsearch.xpack.core.XPackField;
import org.elasticsearch.xpack.core.XPackPlugin;
import org.elasticsearch.xpack.core.XPackSettings;
Expand Down Expand Up @@ -228,8 +228,8 @@
import org.elasticsearch.xpack.security.authz.SecuritySearchOperationListener;
import org.elasticsearch.xpack.security.authz.accesscontrol.OptOutQueryCache;
import org.elasticsearch.xpack.security.authz.interceptor.BulkShardRequestInterceptor;
import org.elasticsearch.xpack.security.authz.interceptor.IndicesAliasesRequestInterceptor;
import org.elasticsearch.xpack.security.authz.interceptor.DlsFlsLicenseRequestInterceptor;
import org.elasticsearch.xpack.security.authz.interceptor.IndicesAliasesRequestInterceptor;
import org.elasticsearch.xpack.security.authz.interceptor.RequestInterceptor;
import org.elasticsearch.xpack.security.authz.interceptor.ResizeRequestInterceptor;
import org.elasticsearch.xpack.security.authz.interceptor.SearchRequestInterceptor;
Expand Down Expand Up @@ -351,7 +351,9 @@ public class Security extends Plugin implements SystemIndexPlugin, IngestPlugin,
public static final LicensedFeature.Momentary IP_FILTERING_FEATURE =
LicensedFeature.momentaryLenient(null, "security_ip_filtering", License.OperationMode.GOLD);
public static final LicensedFeature.Momentary AUDITING_FEATURE =
LicensedFeature.momentaryLenient(null, "security_auditing", License.OperationMode.GOLD);
LicensedFeature.momentaryLenient(null, "security-auditing", License.OperationMode.GOLD);
public static final LicensedFeature.Momentary TOKEN_SERVICE_FEATURE =
LicensedFeature.momentaryLenient(null, "security-token-service", License.OperationMode.STANDARD);

private static final String REALMS_FEATURE_FAMILY = "security-realms";
// Builtin realms (file/native) realms are Basic licensed, so don't need to be checked or tracked
Expand Down Expand Up @@ -629,7 +631,7 @@ Collection<Object> createComponents(Client client, ThreadPool threadPool, Cluste
);
final CompositeRolesStore allRolesStore = new CompositeRolesStore(settings, roleProviders,
privilegeStore, threadPool.getThreadContext(), getLicenseState(), fieldPermissionsCache, apiKeyService,
serviceAccountService, dlsBitsetCache.get(),
serviceAccountService, dlsBitsetCache.get(),
new DeprecationRoleDescriptorConsumer(clusterService, threadPool));
securityIndex.get().addStateListener(allRolesStore::onSecurityIndexStateChange);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@
import org.elasticsearch.xpack.core.security.authc.TokenMetadata;
import org.elasticsearch.xpack.core.security.authc.support.Hasher;
import org.elasticsearch.xpack.core.security.authc.support.TokensInvalidationResult;
import org.elasticsearch.xpack.security.Security;
import org.elasticsearch.xpack.security.support.FeatureNotEnabledException;
import org.elasticsearch.xpack.security.support.FeatureNotEnabledException.Feature;
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
Expand Down Expand Up @@ -1591,12 +1592,12 @@ private static String getTokenIdFromDocumentId(String docId) {

private boolean isEnabled() {
return enabled && licenseState.isSecurityEnabled() &&
licenseState.checkFeature(XPackLicenseState.Feature.SECURITY_TOKEN_SERVICE);
Security.TOKEN_SERVICE_FEATURE.check(licenseState);
}

private void ensureEnabled() {
if (licenseState.isSecurityEnabled() == false ||
licenseState.checkFeature(XPackLicenseState.Feature.SECURITY_TOKEN_SERVICE) == false) {
Security.TOKEN_SERVICE_FEATURE.check(licenseState) == false) {
throw LicenseUtils.newComplianceException("security tokens");
}
if (enabled == false) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.license.LicenseUtils;
import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.license.XPackLicenseState.Feature;
import org.elasticsearch.rest.RestRequest;
import org.elasticsearch.xpack.security.Security;
import org.elasticsearch.xpack.security.rest.action.SecurityBaseRestHandler;

/**
Expand All @@ -32,7 +32,7 @@ protected Exception checkFeatureAvailable(RestRequest request) {
Exception failedFeature = super.checkFeatureAvailable(request);
if (failedFeature != null) {
return failedFeature;
} else if (licenseState.checkFeature(Feature.SECURITY_TOKEN_SERVICE)) {
} else if (Security.TOKEN_SERVICE_FEATURE.check(licenseState)) {
return null;
} else {
logger.info("Security tokens are not available under the current [{}] license", licenseState.getOperationMode().description());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package org.elasticsearch.xpack.security.action.oidc;

import com.nimbusds.jwt.JWT;

import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.bulk.BulkAction;
import org.elasticsearch.action.bulk.BulkItemResponse;
Expand All @@ -32,8 +33,7 @@
import org.elasticsearch.env.Environment;
import org.elasticsearch.env.TestEnvironment;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.license.XPackLicenseState.Feature;
import org.elasticsearch.license.MockLicenseState;
import org.elasticsearch.tasks.Task;
import org.elasticsearch.test.ClusterServiceUtils;
import org.elasticsearch.threadpool.ThreadPool;
Expand All @@ -47,13 +47,14 @@
import org.elasticsearch.xpack.core.security.authc.Authentication;
import org.elasticsearch.xpack.core.security.authc.RealmConfig;
import org.elasticsearch.xpack.core.security.authc.oidc.OpenIdConnectRealmSettings;
import org.elasticsearch.xpack.core.security.authc.support.UserRoleMapper;
import org.elasticsearch.xpack.core.security.user.User;
import org.elasticsearch.xpack.core.ssl.SSLService;
import org.elasticsearch.xpack.security.Security;
import org.elasticsearch.xpack.security.authc.Realms;
import org.elasticsearch.xpack.security.authc.TokenService;
import org.elasticsearch.xpack.security.authc.oidc.OpenIdConnectRealm;
import org.elasticsearch.xpack.security.authc.oidc.OpenIdConnectTestCase;
import org.elasticsearch.xpack.core.security.authc.support.UserRoleMapper;
import org.elasticsearch.xpack.security.support.SecurityIndexManager;
import org.junit.After;
import org.junit.Before;
Expand Down Expand Up @@ -181,9 +182,9 @@ public void setup() throws Exception {

final ClusterService clusterService = ClusterServiceUtils.createClusterService(threadPool);

final XPackLicenseState licenseState = mock(XPackLicenseState.class);
final MockLicenseState licenseState = mock(MockLicenseState.class);
when(licenseState.isSecurityEnabled()).thenReturn(true);
when(licenseState.checkFeature(Feature.SECURITY_TOKEN_SERVICE)).thenReturn(true);
when(licenseState.isAllowed(Security.TOKEN_SERVICE_FEATURE)).thenReturn(true);

tokenService = new TokenService(settings, Clock.systemUTC(), client, licenseState, new SecurityContext(settings, threadContext),
securityIndex, securityIndex, clusterService);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@

import org.apache.lucene.search.TotalHits;
import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.action.ActionType;
import org.elasticsearch.action.ActionListener;
import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.ActionResponse;
import org.elasticsearch.action.ActionType;
import org.elasticsearch.action.bulk.BulkAction;
import org.elasticsearch.action.bulk.BulkItemResponse;
import org.elasticsearch.action.bulk.BulkRequest;
Expand All @@ -35,20 +35,16 @@
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.UUIDs;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.core.PathUtils;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.util.concurrent.ThreadContext;
import org.elasticsearch.xcontent.DeprecationHandler;
import org.elasticsearch.xcontent.NamedXContentRegistry;
import org.elasticsearch.xcontent.XContentType;
import org.elasticsearch.core.PathUtils;
import org.elasticsearch.env.Environment;
import org.elasticsearch.env.TestEnvironment;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.index.shard.ShardId;
import org.elasticsearch.license.XPackLicenseState;
import org.elasticsearch.license.XPackLicenseState.Feature;
import org.elasticsearch.license.MockLicenseState;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.tasks.Task;
Expand All @@ -57,6 +53,9 @@
import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.Transport;
import org.elasticsearch.transport.TransportService;
import org.elasticsearch.xcontent.DeprecationHandler;
import org.elasticsearch.xcontent.NamedXContentRegistry;
import org.elasticsearch.xcontent.XContentType;
import org.elasticsearch.xpack.core.XPackSettings;
import org.elasticsearch.xpack.core.security.SecurityContext;
import org.elasticsearch.xpack.core.security.action.saml.SamlInvalidateSessionRequest;
Expand All @@ -68,6 +67,7 @@
import org.elasticsearch.xpack.core.security.authc.esnative.NativeRealmSettings;
import org.elasticsearch.xpack.core.security.authc.saml.SamlRealmSettings;
import org.elasticsearch.xpack.core.security.user.User;
import org.elasticsearch.xpack.security.Security;
import org.elasticsearch.xpack.security.authc.Realms;
import org.elasticsearch.xpack.security.authc.TokenService;
import org.elasticsearch.xpack.security.authc.saml.SamlLogoutRequestHandler;
Expand Down Expand Up @@ -206,9 +206,9 @@ void doExecute(ActionType<Response> action, Request request, ActionListener<Resp
when(securityIndex.aliasName()).thenReturn(".security");
when(securityIndex.freeze()).thenReturn(securityIndex);

final XPackLicenseState licenseState = mock(XPackLicenseState.class);
final MockLicenseState licenseState = mock(MockLicenseState.class);
when(licenseState.isSecurityEnabled()).thenReturn(true);
when(licenseState.checkFeature(Feature.SECURITY_TOKEN_SERVICE)).thenReturn(true);
when(licenseState.isAllowed(Security.TOKEN_SERVICE_FEATURE)).thenReturn(true);

final ClusterService clusterService = ClusterServiceUtils.createClusterService(threadPool);
final SecurityContext securityContext = new SecurityContext(settings, threadContext);
Expand Down
Loading

0 comments on commit 3e09876

Please sign in to comment.