From 0cb207f83d55ddecc1ce4507cbdf0e1d2efb91fe Mon Sep 17 00:00:00 2001 From: Eric Evans Date: Tue, 28 Sep 2010 23:00:54 +0000 Subject: [PATCH] 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 --- build.xml | 1 + conf/access.properties | 8 +- .../cassandra/auth/SimpleAuthority.java | 29 ++++++-- test/conf/access.properties | 26 +++++++ .../cassandra/auth/SimpleAuthorityTest.java | 73 +++++++++++++++++++ 5 files changed, 127 insertions(+), 10 deletions(-) create mode 100644 test/conf/access.properties create mode 100644 test/unit/org/apache/cassandra/auth/SimpleAuthorityTest.java diff --git a/build.xml b/build.xml index 3778120edb..74ea9aaed5 100644 --- a/build.xml +++ b/build.xml @@ -431,6 +431,7 @@ + diff --git a/conf/access.properties b/conf/access.properties index 4e66732f88..479fed6f84 100644 --- a/conf/access.properties +++ b/conf/access.properties @@ -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 '' property lists users who can modify the +# list of keyspaces: all users will be able to view the list of keyspaces. +=jsmith Keyspace1=jsmith,Elvis Presley,dilbert diff --git a/src/java/org/apache/cassandra/auth/SimpleAuthority.java b/src/java/org/apache/cassandra/auth/SimpleAuthority.java index 33af7c919b..b014c45383 100644 --- a/src/java/org/apache/cassandra/auth/SimpleAuthority.java +++ b/src/java/org/apache/cassandra/auth/SimpleAuthority.java @@ -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 = ""; @Override public EnumSet authorize(AuthenticatedUser user, List 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 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 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; diff --git a/test/conf/access.properties b/test/conf/access.properties new file mode 100644 index 0000000000..e6ffd9f21c --- /dev/null +++ b/test/conf/access.properties @@ -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 '' property lists users who can modify the +# list of keyspaces: all users will be able to view the list of keyspaces. +=user1 +Keyspace1=user1,user2 diff --git a/test/unit/org/apache/cassandra/auth/SimpleAuthorityTest.java b/test/unit/org/apache/cassandra/auth/SimpleAuthorityTest.java new file mode 100644 index 0000000000..0660954531 --- /dev/null +++ b/test/unit/org/apache/cassandra/auth/SimpleAuthorityTest.java @@ -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 KEYSPACES_RESOURCE = Arrays.asList(Resources.ROOT, Resources.KEYSPACES); + private final List KEYSPACE1_RESOURCE = Arrays.asList(Resources.ROOT, Resources.KEYSPACES, "Keyspace1"); + private final List KEYSPACE2_RESOURCE = Arrays.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)); + } +}