Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PkiRealm] Invalidate cache on role mappings change #31510

Merged
merged 4 commits into from
Jun 22, 2018
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 @@ -86,6 +86,7 @@ public PkiRealm(RealmConfig config, ResourceWatcherService watcherService, Nativ
this.trustManager = trustManagers(config);
this.principalPattern = PkiRealmSettings.USERNAME_PATTERN_SETTING.get(config.settings());
this.roleMapper = roleMapper;
this.roleMapper.refreshRealmOnChange(this);
this.cache = CacheBuilder.<BytesKey, User>builder()
.setExpireAfterWrite(PkiRealmSettings.CACHE_TTL_SETTING.get(config.settings()))
.setMaximumWeight(PkiRealmSettings.CACHE_MAX_USERS_SETTING.get(config.settings()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
*/
public interface CachingRealm {

/**
* @return The name of this realm.
*/
String name();

/**
* Expires a single user from the cache identified by the String agument
* @param username the identifier of the user to be cleared
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ public DnRoleMapper(RealmConfig config, ResourceWatcherService watcherService) {
}

@Override
public void refreshRealmOnChange(CachingUsernamePasswordRealm realm) {
public void refreshRealmOnChange(CachingRealm realm) {
addListener(realm::expireAll);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public interface UserRoleMapper {
* the whole cluster depending on whether this role-mapper has node-local data or cluster-wide
* data.
*/
void refreshRealmOnChange(CachingUsernamePasswordRealm realm);
void refreshRealmOnChange(CachingRealm realm);

/**
* A representation of a user for whom roles should be mapped.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import org.elasticsearch.action.support.GroupedActionListener;
import org.elasticsearch.watcher.ResourceWatcherService;
import org.elasticsearch.xpack.core.security.authc.RealmConfig;
import org.elasticsearch.xpack.security.authc.support.CachingUsernamePasswordRealm;
import org.elasticsearch.xpack.security.authc.support.CachingRealm;
import org.elasticsearch.xpack.security.authc.support.DnRoleMapper;
import org.elasticsearch.xpack.security.authc.support.UserRoleMapper;

Expand Down Expand Up @@ -48,7 +48,7 @@ public void resolveRoles(UserData user, ActionListener<Set<String>> listener) {
}

@Override
public void refreshRealmOnChange(CachingUsernamePasswordRealm realm) {
public void refreshRealmOnChange(CachingRealm realm) {
this.delegates.forEach(mapper -> mapper.refreshRealmOnChange(realm));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
import org.elasticsearch.xpack.core.security.authc.support.mapper.ExpressionRoleMapping;
import org.elasticsearch.xpack.core.security.authc.support.mapper.expressiondsl.ExpressionModel;
import org.elasticsearch.xpack.core.security.client.SecurityClient;
import org.elasticsearch.xpack.security.authc.support.CachingUsernamePasswordRealm;
import org.elasticsearch.xpack.security.authc.support.CachingRealm;
import org.elasticsearch.xpack.security.authc.support.UserRoleMapper;
import org.elasticsearch.xpack.security.support.SecurityIndexManager;

Expand Down Expand Up @@ -369,7 +369,7 @@ public void resolveRoles(UserData user, ActionListener<Set<String>> listener) {
* @see ClearRealmCacheAction
*/
@Override
public void refreshRealmOnChange(CachingUsernamePasswordRealm realm) {
public void refreshRealmOnChange(CachingRealm realm) {
realmsToRefresh.add(realm.name());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;

public class PkiRealmTests extends ESTestCase {
Expand Down Expand Up @@ -104,6 +105,7 @@ private void assertSuccessfulAuthentication(Set<String> roles) throws Exception
UserRoleMapper roleMapper = mock(UserRoleMapper.class);
PkiRealm realm = new PkiRealm(new RealmConfig("", Settings.EMPTY, globalSettings, TestEnvironment.newEnvironment(globalSettings),
new ThreadContext(globalSettings)), roleMapper);
verify(roleMapper).refreshRealmOnChange(realm);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about adding a verifyNoMoreInteractions(roleMapper) at the end of this test

Mockito.doAnswer(invocation -> {
final UserRoleMapper.UserData userData = (UserRoleMapper.UserData) invocation.getArguments()[0];
final ActionListener<Set<String>> listener = (ActionListener<Set<String>>) invocation.getArguments()[1];
Expand Down Expand Up @@ -144,6 +146,7 @@ private void assertSuccessfulAuthentication(Set<String> roles) throws Exception

final int numTimes = invalidate ? 2 : 1;
verify(roleMapper, times(numTimes)).resolveRoles(any(UserRoleMapper.UserData.class), any(ActionListener.class));
verifyNoMoreInteractions(roleMapper);
}

public void testCustomUsernamePattern() throws Exception {
Expand Down