mirror of https://github.com/apache/cassandra
182 lines
7.4 KiB
Java
182 lines
7.4 KiB
Java
/*
|
|
* Licensed to the Apache Software Foundation (ASF) under one
|
|
* or more contributor license agreements. See the NOTICE file
|
|
* distributed with this work for additional information
|
|
* regarding copyright ownership. The ASF licenses this file
|
|
* to you under the Apache License, Version 2.0 (the
|
|
* "License"); you may not use this file except in compliance
|
|
* with the License. You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package org.apache.cassandra.auth;
|
|
|
|
import java.util.Arrays;
|
|
import java.util.HashSet;
|
|
import java.util.Map;
|
|
import java.util.Set;
|
|
import java.util.stream.Collectors;
|
|
|
|
import com.google.common.collect.Iterables;
|
|
|
|
import org.assertj.core.api.Assertions;
|
|
import org.junit.Assert;
|
|
import org.junit.BeforeClass;
|
|
import org.junit.Test;
|
|
|
|
import org.apache.cassandra.SchemaLoader;
|
|
import org.apache.cassandra.config.DatabaseDescriptor;
|
|
import org.apache.cassandra.db.ConsistencyLevel;
|
|
|
|
import static org.apache.cassandra.auth.AuthTestUtils.ALL_ROLES;
|
|
import static org.apache.cassandra.auth.AuthTestUtils.ROLE_A;
|
|
import static org.apache.cassandra.auth.AuthTestUtils.ROLE_B;
|
|
import static org.apache.cassandra.auth.AuthTestUtils.ROLE_B_1;
|
|
import static org.apache.cassandra.auth.AuthTestUtils.ROLE_B_2;
|
|
import static org.apache.cassandra.auth.AuthTestUtils.ROLE_C;
|
|
import static org.apache.cassandra.auth.AuthTestUtils.getRolesReadCount;
|
|
import static org.apache.cassandra.auth.AuthTestUtils.grantRolesTo;
|
|
import static org.junit.Assert.assertEquals;
|
|
import static org.junit.Assert.assertTrue;
|
|
|
|
public class RolesTest
|
|
{
|
|
|
|
@BeforeClass
|
|
public static void setupClass()
|
|
{
|
|
SchemaLoader.prepareServer();
|
|
IRoleManager roleManager = new AuthTestUtils.LocalCassandraRoleManager();
|
|
SchemaLoader.setupAuth(roleManager,
|
|
new AuthTestUtils.LocalPasswordAuthenticator(),
|
|
new AuthTestUtils.LocalCassandraAuthorizer(),
|
|
new AuthTestUtils.LocalCassandraNetworkAuthorizer(),
|
|
new AuthTestUtils.LocalCassandraCIDRAuthorizer());
|
|
|
|
for (RoleResource role : ALL_ROLES)
|
|
roleManager.createRole(AuthenticatedUser.ANONYMOUS_USER, role, new RoleOptions());
|
|
grantRolesTo(roleManager, ROLE_A, ROLE_B, ROLE_C);
|
|
|
|
RoleOptions roleOptions = new RoleOptions();
|
|
roleOptions.setOption(IRoleManager.Option.SUPERUSER, true);
|
|
RoleResource testSuperUser = RoleResource.role("testSuperuser");
|
|
roleManager.createRole(AuthenticatedUser.ANONYMOUS_USER, testSuperUser, roleOptions);
|
|
grantRolesTo(roleManager, ROLE_B_1, testSuperUser);
|
|
grantRolesTo(roleManager, ROLE_B_2, ROLE_B_1);
|
|
|
|
roleManager.setup();
|
|
AuthCacheService.initializeAndRegisterCaches();
|
|
}
|
|
|
|
@Test
|
|
public void superuserStatusIsCached()
|
|
{
|
|
boolean hasSuper = Roles.hasSuperuserStatus(ROLE_A);
|
|
long count = getRolesReadCount();
|
|
|
|
assertEquals(hasSuper, Roles.hasSuperuserStatus(ROLE_A));
|
|
assertEquals(count, getRolesReadCount());
|
|
}
|
|
|
|
@Test
|
|
public void loginPrivilegeIsCached()
|
|
{
|
|
boolean canLogin = Roles.canLogin(ROLE_A);
|
|
long count = getRolesReadCount();
|
|
|
|
assertEquals(canLogin, Roles.canLogin(ROLE_A));
|
|
assertEquals(count, getRolesReadCount());
|
|
}
|
|
|
|
@Test
|
|
public void grantedRoleDetailsAreCached()
|
|
{
|
|
Iterable<Role> granted = Roles.getRoleDetails(ROLE_A);
|
|
long count = getRolesReadCount();
|
|
|
|
assertTrue(Iterables.elementsEqual(granted, Roles.getRoleDetails(ROLE_A)));
|
|
assertEquals(count, getRolesReadCount());
|
|
}
|
|
|
|
@Test
|
|
public void grantedRoleResourcesAreCached()
|
|
{
|
|
Set<RoleResource> granted = Roles.getRoles(ROLE_A);
|
|
long count = getRolesReadCount();
|
|
|
|
assertEquals(granted, Roles.getRoles(ROLE_A));
|
|
assertEquals(count, getRolesReadCount());
|
|
}
|
|
|
|
@Test
|
|
public void confirmSuperUserConsistency()
|
|
{
|
|
// Confirm special treatment of superuser
|
|
ConsistencyLevel readLevel = CassandraRoleManager.consistencyForRoleRead(CassandraRoleManager.DEFAULT_SUPERUSER_NAME);
|
|
Assert.assertEquals(CassandraRoleManager.DEFAULT_SUPERUSER_CONSISTENCY_LEVEL, readLevel);
|
|
|
|
ConsistencyLevel writeLevel = CassandraRoleManager.consistencyForRoleWrite(CassandraRoleManager.DEFAULT_SUPERUSER_NAME);
|
|
Assert.assertEquals(CassandraRoleManager.DEFAULT_SUPERUSER_CONSISTENCY_LEVEL, writeLevel);
|
|
|
|
// Confirm standard config-based treatment of non
|
|
ConsistencyLevel nonPrivReadLevel = CassandraRoleManager.consistencyForRoleRead("non-privilaged");
|
|
Assert.assertEquals(nonPrivReadLevel, DatabaseDescriptor.getAuthReadConsistencyLevel());
|
|
|
|
ConsistencyLevel nonPrivWriteLevel = CassandraRoleManager.consistencyForRoleWrite("non-privilaged");
|
|
Assert.assertEquals(nonPrivWriteLevel, DatabaseDescriptor.getAuthWriteConsistencyLevel());
|
|
}
|
|
|
|
@Test
|
|
public void confirmSuperUserConsistencyWithConfiguredDefaultRoleName()
|
|
{
|
|
IDefaultRoleInitializer previous = DatabaseDescriptor.getDefaultRoleInitializer();
|
|
String customRole = "cassandra_mtls_custom_test_role";
|
|
try
|
|
{
|
|
DatabaseDescriptor.setDefaultRoleInitializer(new MutualTlsDefaultRoleInitializer(Map.of("role", customRole, "identity", "spiffe1")));
|
|
|
|
ConsistencyLevel readLevel = CassandraRoleManager.consistencyForRoleRead(customRole);
|
|
Assert.assertEquals(CassandraRoleManager.DEFAULT_SUPERUSER_CONSISTENCY_LEVEL, readLevel);
|
|
|
|
ConsistencyLevel writeLevel = CassandraRoleManager.consistencyForRoleWrite(customRole);
|
|
Assert.assertEquals(CassandraRoleManager.DEFAULT_SUPERUSER_CONSISTENCY_LEVEL, writeLevel);
|
|
|
|
ConsistencyLevel legacyReadLevel = CassandraRoleManager.consistencyForRoleRead(CassandraRoleManager.DEFAULT_SUPERUSER_NAME);
|
|
Assert.assertEquals(legacyReadLevel, DatabaseDescriptor.getAuthReadConsistencyLevel());
|
|
|
|
ConsistencyLevel legacyWriteLevel = CassandraRoleManager.consistencyForRoleWrite(CassandraRoleManager.DEFAULT_SUPERUSER_NAME);
|
|
Assert.assertEquals(legacyWriteLevel, DatabaseDescriptor.getAuthWriteConsistencyLevel());
|
|
}
|
|
finally
|
|
{
|
|
DatabaseDescriptor.setDefaultRoleInitializer(previous);
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void testSuperUsers()
|
|
{
|
|
Assert.assertEquals(new HashSet<>(Arrays.asList("testSuperuser", "role_b_1", "role_b_2")),
|
|
Roles.getAllRoles(Roles::hasSuperuserStatus)
|
|
.stream()
|
|
.map(RoleResource::getRoleName)
|
|
.collect(Collectors.toSet()));
|
|
}
|
|
|
|
@Test
|
|
public void testNonexistentRoleCantLogin()
|
|
{
|
|
// There can be a reference to a nonexistent role (that has been removed from the cache and the system table)
|
|
// via the native transport connection state, make sure there's no NPE on canLogin check
|
|
AuthenticatedUser nonexistent = new AuthenticatedUser("nonexistent");
|
|
Assertions.assertThat(nonexistent.canLogin()).isFalse();
|
|
}
|
|
}
|