Make SimpleAuthority aware of the keyspace list resource.

Patch by Stu Hood; reviewed by eevans for CASSANDRA-1271

git-svn-id: https://svn.apache.org/repos/asf/cassandra/trunk@1002401 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Eric Evans 2010-09-28 23:00:54 +00:00
parent cec1d5157a
commit 0cb207f83d
5 changed files with 127 additions and 10 deletions

View File

@ -431,6 +431,7 @@
<formatter type="xml" usefile="true"/>
<formatter type="brief" usefile="false"/>
<jvmarg value="-Dstorage-config=${test.conf}"/>
<jvmarg value="-Daccess.properties=${test.conf}/access.properties"/>
<jvmarg value="-Dlog4j.configuration=log4j-junit.properties" />
<jvmarg value="-Dlegacy-sstable-root=${test.data}/legacy-sstables"/>
<jvmarg value="-ea"/>

View File

@ -13,10 +13,14 @@
# 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.
#
# This is a sample access file for SimpleAuthenticator. The format of
# This is a sample access file for SimpleAuthority. The format of
# this file is keyspace=users, where users is a comma delimited list of
# authenticatable users from passwd.properties. This file contains
# potentially sensitive information, keep this in mind when setting its
# mode and ownership.
#
# The magical '<modify-keyspaces>' property lists users who can modify the
# list of keyspaces: all users will be able to view the list of keyspaces.
<modify-keyspaces>=jsmith
Keyspace1=jsmith,Elvis Presley,dilbert

View File

@ -31,18 +31,33 @@ import org.apache.cassandra.config.ConfigurationException;
public class SimpleAuthority implements IAuthority
{
public final static String ACCESS_FILENAME_PROPERTY = "access.properties";
// magical property for WRITE permissions to the keyspaces list
public final static String KEYSPACES_WRITE_PROPERTY = "<modify-keyspaces>";
@Override
public EnumSet<Permission> authorize(AuthenticatedUser user, List<Object> resource)
{
if (resource.size() < 3 || !Resources.ROOT.equals(resource.get(0)) || !Resources.KEYSPACES.equals(resource.get(1)))
// unable to handle resources in other portions of the hierarchy
if (resource.size() < 2 || !Resources.ROOT.equals(resource.get(0)) || !Resources.KEYSPACES.equals(resource.get(1)))
// we only know how to handle keyspace authorization
return Permission.NONE;
String keyspace = (String)resource.get(2);
String keyspace;
EnumSet<Permission> authorized;
if (resource.size() < 3)
{
// authorize the user for the keyspace list using the 'magical' keyspace,
// but give them read access by default
keyspace = KEYSPACES_WRITE_PROPERTY;
authorized = EnumSet.of(Permission.READ);
}
else
{
// otherwise, authorize them for the actual keyspace
keyspace = (String)resource.get(2);
authorized = Permission.NONE;
}
String afilename = System.getProperty(ACCESS_FILENAME_PROPERTY);
EnumSet<Permission> authorized = Permission.NONE;
try
{
FileInputStream in = new FileInputStream(afilename);
@ -54,11 +69,9 @@ public class SimpleAuthority implements IAuthority
// given keyspace X, users A B and C can be authorized like this (separate their names with spaces):
// X = A B C
// note we keep the message here and for other authorization problems exactly the same to prevent attackers
// from guessing what keyspaces are valid
if (null == props.getProperty(keyspace))
// no one is authorized
return authorized;
for (String allow : props.getProperty(keyspace).split(","))
if (allow.equals(user.username))
authorized = Permission.ALL;

View File

@ -0,0 +1,26 @@
# 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.
# This is a sample access file for SimpleAuthority. The format of
# this file is keyspace=users, where users is a comma delimited list of
# authenticatable users from passwd.properties. This file contains
# potentially sensitive information, keep this in mind when setting its
# mode and ownership.
#
# The magical '<modify-keyspaces>' property lists users who can modify the
# list of keyspaces: all users will be able to view the list of keyspaces.
<modify-keyspaces>=user1
Keyspace1=user1,user2

View File

@ -0,0 +1,73 @@
/*
* 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.EnumSet;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class SimpleAuthorityTest
{
private final SimpleAuthority authority = new SimpleAuthority();
private final AuthenticatedUser USER1 = new AuthenticatedUser("user1");
private final AuthenticatedUser USER2 = new AuthenticatedUser("user2");
private final AuthenticatedUser USER3 = new AuthenticatedUser("user3");
private final List<Object> KEYSPACES_RESOURCE = Arrays.<Object>asList(Resources.ROOT, Resources.KEYSPACES);
private final List<Object> KEYSPACE1_RESOURCE = Arrays.<Object>asList(Resources.ROOT, Resources.KEYSPACES, "Keyspace1");
private final List<Object> KEYSPACE2_RESOURCE = Arrays.<Object>asList(Resources.ROOT, Resources.KEYSPACES, "Keyspace2");
@Test
public void testValidateConfiguration() throws Exception
{
authority.validateConfiguration();
}
@Test
public void testAuthorizeKeyspace() throws Exception
{
assertEquals(Permission.ALL, authority.authorize(USER1, KEYSPACE1_RESOURCE));
assertEquals(Permission.ALL, authority.authorize(USER2, KEYSPACE1_RESOURCE));
assertEquals(Permission.NONE, authority.authorize(USER3, KEYSPACE1_RESOURCE));
assertEquals("a keyspace not listed in the access file should be inaccessible",
Permission.NONE,
authority.authorize(USER1, KEYSPACE2_RESOURCE));
}
@Test
public void testAuthorizeKeyspaceList() throws Exception
{
assertEquals("user1 should be able to modify the keyspace list",
Permission.ALL,
authority.authorize(USER1, KEYSPACES_RESOURCE));
assertEquals("user2 should only be able to read the keyspace list",
EnumSet.of(Permission.READ),
authority.authorize(USER2, KEYSPACES_RESOURCE));
assertEquals("user3 should only be able to read the keyspace list",
EnumSet.of(Permission.READ),
authority.authorize(USER3, KEYSPACES_RESOURCE));
}
}