Skip to content

Commit

Permalink
Remove combo security and license helper from license state (elastic#…
Browse files Browse the repository at this point in the history
…55366)

Security features in the license state currently do a dynamic check on
whether security is enabled. This is because the license level can
change the default security enabled state. This commit splits out the
check on security being enabled, so that the combo method of security
enabled plus license allowed is no longer necessary.
  • Loading branch information
rjernst committed Apr 17, 2020
1 parent 49e30b1 commit ab0fb44
Show file tree
Hide file tree
Showing 37 changed files with 61 additions and 58 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -402,11 +402,11 @@ boolean isActive() {
}

public boolean isIpFilteringAllowed() {
return isAllowedBySecurityAndLicense(OperationMode.GOLD, false);
return isAllowedByLicense(OperationMode.GOLD, false);
}

public boolean isAuditingAllowed() {
return isAllowedBySecurityAndLicense(OperationMode.GOLD, false);
return isAllowedByLicense(OperationMode.GOLD, false);
}

public boolean isStatsAndHealthAllowed() {
Expand All @@ -427,49 +427,49 @@ public boolean isStatsAndHealthAllowed() {
* @return {@code true} to enable DLS and FLS. Otherwise {@code false}.
*/
public boolean isDocumentAndFieldLevelSecurityAllowed() {
return isAllowedBySecurityAndLicense(OperationMode.PLATINUM, false);
return isAllowedByLicense(OperationMode.PLATINUM, false);
}

public boolean areAllRealmsAllowed() {
return isAllowedBySecurityAndLicense(OperationMode.PLATINUM, false);
return isAllowedByLicense(OperationMode.PLATINUM, false);
}

public boolean areStandardRealmsAllowed() {
return isAllowedBySecurityAndLicense(OperationMode.GOLD, false);
return isAllowedByLicense(OperationMode.GOLD, false);
}

public boolean isCustomRoleProvidersAllowed() {
return isAllowedBySecurityAndLicense(OperationMode.PLATINUM, true);
return isAllowedByLicense(OperationMode.PLATINUM, true);
}

/**
* Whether the Elasticsearch {@code TokenService} is allowed
*/
public boolean isTokenServiceAllowed() {
return isAllowedBySecurityAndLicense(OperationMode.GOLD, false);
return isAllowedByLicense(OperationMode.GOLD, false);
}

/**
* Whether the Elasticsearch {@code ApiKeyService} is allowed
*/
public boolean isApiKeyServiceAllowed() {
return isAllowedBySecurityAndLicense(OperationMode.MISSING, false);
return isAllowedByLicense(OperationMode.MISSING, false);
}

/**
* Whether "authorization_realms" is allowed
* @see org.elasticsearch.xpack.core.security.authc.support.DelegatedAuthorizationSettings
*/
public boolean isAuthorizationRealmAllowed() {
return isAllowedBySecurityAndLicense(OperationMode.PLATINUM, true);
return isAllowedByLicense(OperationMode.PLATINUM, true);
}

/**
* Whether a custom authorization engine is allowed
* @see org.elasticsearch.xpack.core.security.authc.support.DelegatedAuthorizationSettings
*/
public boolean isAuthorizationEngineAllowed() {
return isAllowedBySecurityAndLicense(OperationMode.PLATINUM, true);
return isAllowedByLicense(OperationMode.PLATINUM, true);
}

public boolean isWatcherAllowed() {
Expand Down Expand Up @@ -683,32 +683,7 @@ public XPackLicenseState copyCurrentLicenseState() {
}

/**
* Test whether a feature is allowed by the status of license and security configuration.
* Note the difference to {@link #isAllowedByLicense(OperationMode, boolean)}
* is this method requires security to be enabled.
*
* @param minimumMode The minimum license to meet or exceed
* @param needActive Whether current license needs to be active.
*
* @return true if feature is allowed, otherwise false
*/
private boolean isAllowedBySecurityAndLicense(OperationMode minimumMode, boolean needActive) {
return checkAgainstStatus(status -> {
if (false == isSecurityEnabled(status.mode, isSecurityExplicitlyEnabled, isSecurityEnabled)) {
return false;
}
// Do not delegate to isAllowedByLicense as it also captures "status" which may be different from here
if (needActive && false == status.active) {
return false;
}
return isAllowedByOperationMode(status.mode, minimumMode);
});
}

/**
* Test whether a feature is allowed by the status of license. Note difference to
* {@link #isAllowedBySecurityAndLicense} is this method does <b>Not</b> require security
* to be enabled.
* Test whether a feature is allowed by the status of license.
*
* @param minimumMode The minimum license to meet or exceed
* @param needActive Whether current license needs to be active
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public SecurityIndexReaderWrapper(Function<ShardId, QueryShardContext> queryShar

@Override
public DirectoryReader apply(final DirectoryReader reader) {
if (licenseState.isDocumentAndFieldLevelSecurityAllowed() == false) {
if (licenseState.isSecurityEnabled() == false || licenseState.isDocumentAndFieldLevelSecurityAllowed() == false) {
return reader;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public void testSecurityBasicWithoutExplicitSecurityEnabled() {
assertThat(licenseState.isDocumentAndFieldLevelSecurityAllowed(), is(false));
assertThat(licenseState.isCustomRoleProvidersAllowed(), is(false));
assertThat(licenseState.isTokenServiceAllowed(), is(false));
assertThat(licenseState.isApiKeyServiceAllowed(), is(false));
assertThat(licenseState.isApiKeyServiceAllowed(), is(true));

assertThat(licenseState.isSecurityAvailable(), is(true));
assertThat(licenseState.isSecurityEnabled(), is(false));
Expand Down Expand Up @@ -142,7 +142,7 @@ public void testSecurityDefaultBasicExpired() {
assertThat(licenseState.isDocumentAndFieldLevelSecurityAllowed(), is(false));
assertThat(licenseState.isCustomRoleProvidersAllowed(), is(false));
assertThat(licenseState.isTokenServiceAllowed(), is(false));
assertThat(licenseState.isApiKeyServiceAllowed(), is(false));
assertThat(licenseState.isApiKeyServiceAllowed(), is(true));
}

public void testSecurityEnabledBasicExpired() {
Expand Down Expand Up @@ -260,11 +260,6 @@ public void testNewTrialDefaultsSecurityOff() {

private void assertSecurityNotAllowed(XPackLicenseState licenseState) {
assertThat(licenseState.isSecurityEnabled(), is(false));
assertThat(licenseState.isIpFilteringAllowed(), is(false));
assertThat(licenseState.isAuditingAllowed(), is(false));
assertThat(licenseState.isStatsAndHealthAllowed(), is(true));
assertThat(licenseState.isDocumentAndFieldLevelSecurityAllowed(), is(false));
assertThat(licenseState.isCustomRoleProvidersAllowed(), is(false));
}

public void testSecurityAckBasicToNotGoldOrStandard() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ null, null, mapperService, null, null, xContentRegistry(), writableRegistry(),
QueryShardContext queryShardContext = spy(realQueryShardContext);
DocumentSubsetBitsetCache bitsetCache = new DocumentSubsetBitsetCache(Settings.EMPTY, Executors.newSingleThreadExecutor());
XPackLicenseState licenseState = mock(XPackLicenseState.class);
when(licenseState.isSecurityEnabled()).thenReturn(true);
when(licenseState.isDocumentAndFieldLevelSecurityAllowed()).thenReturn(true);

Directory directory = newDirectory();
Expand Down Expand Up @@ -232,6 +233,7 @@ null, null, mapperService, null, null, xContentRegistry(), writableRegistry(),
DocumentSubsetBitsetCache bitsetCache = new DocumentSubsetBitsetCache(Settings.EMPTY, Executors.newSingleThreadExecutor());

XPackLicenseState licenseState = mock(XPackLicenseState.class);
when(licenseState.isSecurityEnabled()).thenReturn(true);
when(licenseState.isDocumentAndFieldLevelSecurityAllowed()).thenReturn(true);
SecurityIndexReaderWrapper wrapper = new SecurityIndexReaderWrapper(s -> queryShardContext,
bitsetCache, securityContext, licenseState, scriptService) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ public void setup() throws Exception {

ShardId shardId = new ShardId(index, 0);
licenseState = mock(XPackLicenseState.class);
when(licenseState.isSecurityEnabled()).thenReturn(true);
when(licenseState.isDocumentAndFieldLevelSecurityAllowed()).thenReturn(true);
securityContext = new SecurityContext(Settings.EMPTY, new ThreadContext(Settings.EMPTY));
IndexShard indexShard = mock(IndexShard.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1029,7 +1029,8 @@ public UnaryOperator<Map<String, IndexTemplateMetadata>> getIndexTemplateMetadat
public Function<String, Predicate<String>> getFieldFilter() {
if (enabled) {
return index -> {
if (getLicenseState().isDocumentAndFieldLevelSecurityAllowed() == false) {
XPackLicenseState licenseState = getLicenseState();
if (licenseState.isSecurityEnabled() == false || licenseState.isDocumentAndFieldLevelSecurityAllowed() == false) {
return MapperPlugin.NOOP_FIELD_PREDICATE;
}
IndicesAccessControl indicesAccessControl = threadContext.get().getTransient(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ public AuditTrailService(List<AuditTrail> auditTrails, XPackLicenseState license
}

public AuditTrail get() {
if (compositeAuditTrail.isEmpty() == false && licenseState.isAuditingAllowed()) {
if (compositeAuditTrail.isEmpty() == false &&
licenseState.isSecurityEnabled() && licenseState.isAuditingAllowed()) {
return compositeAuditTrail;
} else {
return NOOP_AUDIT_TRAIL;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -581,11 +581,11 @@ private Instant getApiKeyExpiration(Instant now, CreateApiKeyRequest request) {
}

private boolean isEnabled() {
return enabled && licenseState.isApiKeyServiceAllowed();
return enabled && licenseState.isSecurityEnabled() && licenseState.isApiKeyServiceAllowed();
}

public void ensureEnabled() {
if (licenseState.isApiKeyServiceAllowed() == false) {
if (licenseState.isSecurityEnabled() == false || licenseState.isApiKeyServiceAllowed() == false) {
throw LicenseUtils.newComplianceException("api keys");
}
if (enabled == false) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1519,11 +1519,11 @@ private static String getTokenIdFromDocumentId(String docId) {
}

private boolean isEnabled() {
return enabled && licenseState.isTokenServiceAllowed();
return enabled && licenseState.isSecurityEnabled() && licenseState.isTokenServiceAllowed();
}

private void ensureEnabled() {
if (licenseState.isTokenServiceAllowed() == false) {
if (licenseState.isSecurityEnabled() == false || licenseState.isTokenServiceAllowed() == false) {
throw LicenseUtils.newComplianceException("security tokens");
}
if (enabled == false) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ public boolean hasDelegation() {
* with a meaningful diagnostic message.
*/
public void resolve(String username, ActionListener<AuthenticationResult> resultListener) {
if (licenseState.isAuthorizationRealmAllowed() == false) {
boolean authzOk = licenseState.isSecurityEnabled() && licenseState.isAuthorizationRealmAllowed();
if (authzOk == false) {
resultListener.onResponse(AuthenticationResult.unsuccessful(
DelegatedAuthorizationSettings.AUTHZ_REALMS_SUFFIX + " are not permitted",
LicenseUtils.newComplianceException(DelegatedAuthorizationSettings.AUTHZ_REALMS_SUFFIX)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ AuthorizationEngine getAuthorizationEngine(final Authentication authentication)
}

private AuthorizationEngine getAuthorizationEngineForUser(final User user) {
if (rbacEngine != authorizationEngine && licenseState.isAuthorizationEngineAllowed()) {
if (rbacEngine != authorizationEngine && licenseState.isSecurityEnabled() && licenseState.isAuthorizationEngineAllowed()) {
if (ClientReservedRealm.isReserved(user.principal(), settings) || isInternalUser(user)) {
return rbacEngine;
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ public BulkShardRequestInterceptor(ThreadPool threadPool, XPackLicenseState lice
@Override
public void intercept(RequestInfo requestInfo, AuthorizationEngine authzEngine, AuthorizationInfo authorizationInfo,
ActionListener<Void> listener) {
if (requestInfo.getRequest() instanceof BulkShardRequest && licenseState.isDocumentAndFieldLevelSecurityAllowed()) {
boolean shouldIntercept = licenseState.isSecurityEnabled() && licenseState.isDocumentAndFieldLevelSecurityAllowed();
if (requestInfo.getRequest() instanceof BulkShardRequest && shouldIntercept) {
IndicesAccessControl indicesAccessControl = threadContext.getTransient(AuthorizationServiceField.INDICES_PERMISSIONS_KEY);

final BulkShardRequest bulkShardRequest = (BulkShardRequest) requestInfo.getRequest();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ public void intercept(RequestInfo requestInfo, AuthorizationEngine authorization
ActionListener<Void> listener) {
if (requestInfo.getRequest() instanceof IndicesRequest) {
IndicesRequest indicesRequest = (IndicesRequest) requestInfo.getRequest();
if (supports(indicesRequest) && licenseState.isDocumentAndFieldLevelSecurityAllowed()) {
boolean shouldIntercept = licenseState.isSecurityEnabled() && licenseState.isDocumentAndFieldLevelSecurityAllowed();
if (supports(indicesRequest) && shouldIntercept) {
final IndicesAccessControl indicesAccessControl =
threadContext.getTransient(AuthorizationServiceField.INDICES_PERMISSIONS_KEY);
for (String index : indicesRequest.indices()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ private void setHttpFiltering(boolean enabled) {
}

public boolean accept(String profile, InetSocketAddress peerAddress) {
if (licenseState.isIpFilteringAllowed() == false) {
if (licenseState.isSecurityEnabled() == false || licenseState.isIpFilteringAllowed() == false) {
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ public void setup() throws Exception {
final ClusterService clusterService = ClusterServiceUtils.createClusterService(threadPool);

final XPackLicenseState licenseState = mock(XPackLicenseState.class);
when(licenseState.isSecurityEnabled()).thenReturn(true);
when(licenseState.isTokenServiceAllowed()).thenReturn(true);

tokenService = new TokenService(settings, Clock.systemUTC(), client, licenseState, new SecurityContext(settings, threadContext),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ void doExecute(ActionType<Response> action, Request request, ActionListener<Resp
when(securityIndex.freeze()).thenReturn(securityIndex);

final XPackLicenseState licenseState = mock(XPackLicenseState.class);
when(licenseState.isSecurityEnabled()).thenReturn(true);
when(licenseState.isTokenServiceAllowed()).thenReturn(true);

final ClusterService clusterService = ClusterServiceUtils.createClusterService(threadPool);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ public void setup() throws Exception {
when(securityIndex.freeze()).thenReturn(securityIndex);

final XPackLicenseState licenseState = mock(XPackLicenseState.class);
when(licenseState.isSecurityEnabled()).thenReturn(true);
when(licenseState.isTokenServiceAllowed()).thenReturn(true);
final ClusterService clusterService = ClusterServiceUtils.createClusterService(threadPool);
final SecurityContext securityContext = new SecurityContext(settings, threadContext);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ && new String((byte[]) token.credentials(), StandardCharsets.UTF_8).equals("fail
this.clusterService = ClusterServiceUtils.createClusterService(threadPool);

this.license = mock(XPackLicenseState.class);
when(license.isSecurityEnabled()).thenReturn(true);
when(license.isTokenServiceAllowed()).thenReturn(true);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ public void setup() {
securityIndex = mock(SecurityIndexManager.class);
this.clusterService = ClusterServiceUtils.createClusterService(threadPool);
this.license = mock(XPackLicenseState.class);
when(license.isSecurityEnabled()).thenReturn(true);
when(license.isTokenServiceAllowed()).thenReturn(true);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public void init() throws Exception {
licenseState = mock(XPackLicenseState.class);
service = new AuditTrailService(auditTrails, licenseState);
isAuditingAllowed = randomBoolean();
when(licenseState.isSecurityEnabled()).thenReturn(true);
when(licenseState.isAuditingAllowed()).thenReturn(isAuditingAllowed);
token = mock(AuthenticationToken.class);
request = mock(TransportRequest.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ public void stopThreadPool() {
@Before
public void setupMocks() {
this.licenseState = mock(XPackLicenseState.class);
when(licenseState.isSecurityEnabled()).thenReturn(true);
when(licenseState.isApiKeyServiceAllowed()).thenReturn(true);

this.client = mock(Client.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ public void setupClient() {

// License state (enabled by default)
licenseState = mock(XPackLicenseState.class);
when(licenseState.isSecurityEnabled()).thenReturn(true);
when(licenseState.isTokenServiceAllowed()).thenReturn(true);

// version 7.2 was an "inflection" point in the Token Service development (access_tokens as UUIDS, multiple concurrent refreshes,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ public void setup() throws Exception {
settings = buildKerberosRealmSettings(REALM_NAME,
writeKeyTab(dir.resolve("key.keytab"), "asa").toString(), 100, "10m", true, randomBoolean());
licenseState = mock(XPackLicenseState.class);
when(licenseState.isSecurityEnabled()).thenReturn(true);
when(licenseState.isAuthorizationRealmAllowed()).thenReturn(true);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ public void init() throws Exception {
defaultGlobalSettings = builder.put("path.home", createTempDir()).build();
sslService = new SSLService(defaultGlobalSettings, TestEnvironment.newEnvironment(defaultGlobalSettings));
licenseState = mock(XPackLicenseState.class);
when(licenseState.isSecurityEnabled()).thenReturn(true);
when(licenseState.isAuthorizationRealmAllowed()).thenReturn(true);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ private AuthenticationResult authenticateWithOidc(String principal, UserRoleMapp

private void initializeRealms(Realm... realms) {
XPackLicenseState licenseState = mock(XPackLicenseState.class);
when(licenseState.isSecurityEnabled()).thenReturn(true);
when(licenseState.isAuthorizationRealmAllowed()).thenReturn(true);

final List<Realm> realmList = Arrays.asList(realms);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ public void setup() throws Exception {
.put("path.home", createTempDir())
.build();
licenseState = mock(XPackLicenseState.class);
when(licenseState.isSecurityEnabled()).thenReturn(true);
when(licenseState.isAuthorizationRealmAllowed()).thenReturn(true);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ private AuthenticationResult performAuthentication(UserRoleMapper roleMapper, bo

private void initializeRealms(Realm... realms) {
XPackLicenseState licenseState = mock(XPackLicenseState.class);
when(licenseState.isSecurityEnabled()).thenReturn(true);
when(licenseState.isAuthorizationRealmAllowed()).thenReturn(true);

final List<Realm> realmList = Arrays.asList(realms);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ public void testLicenseRejection() throws Exception {

private XPackLicenseState getLicenseState(boolean authzRealmsAllowed) {
final XPackLicenseState license = mock(XPackLicenseState.class);
when(license.isSecurityEnabled()).thenReturn(true);
when(license.isAuthorizationRealmAllowed()).thenReturn(authzRealmsAllowed);
return license;
}
Expand Down
Loading

0 comments on commit ab0fb44

Please sign in to comment.