cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From eev...@apache.org
Subject svn commit: r989365 - in /cassandra/trunk/src/java/org/apache/cassandra: avro/CassandraServer.java service/ClientState.java thrift/CassandraDaemon.java thrift/CassandraServer.java
Date Wed, 25 Aug 2010 20:41:37 GMT
Author: eevans
Date: Wed Aug 25 20:41:37 2010
New Revision: 989365

URL: http://svn.apache.org/viewvc?rev=989365&view=rev
Log:
Separate authentication and authorization into ClientState object

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

Added:
    cassandra/trunk/src/java/org/apache/cassandra/service/ClientState.java
Modified:
    cassandra/trunk/src/java/org/apache/cassandra/avro/CassandraServer.java
    cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraDaemon.java
    cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java

Modified: cassandra/trunk/src/java/org/apache/cassandra/avro/CassandraServer.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/avro/CassandraServer.java?rev=989365&r1=989364&r2=989365&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/avro/CassandraServer.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/avro/CassandraServer.java Wed Aug 25 20:41:37
2010
@@ -64,8 +64,10 @@ import org.apache.cassandra.db.migration
 import org.apache.cassandra.db.migration.RenameColumnFamily;
 import org.apache.cassandra.locator.AbstractReplicationStrategy;
 import org.apache.cassandra.scheduler.IRequestScheduler;
+import org.apache.cassandra.service.ClientState;
 import org.apache.cassandra.service.StorageProxy;
 import org.apache.cassandra.service.StorageService;
+import org.apache.cassandra.thrift.AccessLevel;
 
 import static org.apache.cassandra.avro.AvroRecordFactory.*;
 import static org.apache.cassandra.avro.ErrorFactory.*;
@@ -88,22 +90,8 @@ public class CassandraServer implements 
     public final static String D_COLDEF_INDEXTYPE = "KEYS";
     public final static String D_COLDEF_INDEXNAME = null;
     
-    private ThreadLocal<AccessLevel> loginDone = new ThreadLocal<AccessLevel>()
-    {
-        @Override
-        protected AccessLevel initialValue()
-        {
-            return AccessLevel.NONE;
-        }
-    };
-    
-    // Session keyspace.
-    private ThreadLocal<String> curKeyspace = new ThreadLocal<String>();
-
-    /*
-     * An associated Id for scheduling the requests
-     */
-    private ThreadLocal<String> requestSchedulerId = new ThreadLocal<String>();
+    // thread local state containing session information
+    private final ClientState clientState = new ClientState();
 
     /*
      * RequestScheduler to perform the scheduling of incoming requests
@@ -121,7 +109,7 @@ public class CassandraServer implements 
         if (logger.isDebugEnabled())
             logger.debug("get");
 
-        AvroValidation.validateColumnPath(curKeyspace.get(), columnPath);
+        AvroValidation.validateColumnPath(clientState.getKeyspace(), columnPath);
         
         // FIXME: This is repetitive.
         byte[] column, super_column;
@@ -131,7 +119,7 @@ public class CassandraServer implements 
         QueryPath path = new QueryPath(columnPath.column_family.toString(), column == null
? null : super_column);
         List<byte[]> nameAsList = Arrays.asList(column == null ? super_column : column);
         AvroValidation.validateKey(key.array());
-        ReadCommand command = new SliceByNamesReadCommand(curKeyspace.get(), key.array(),
path, nameAsList);
+        ReadCommand command = new SliceByNamesReadCommand(clientState.getKeyspace(), key.array(),
path, nameAsList);
         
         Map<DecoratedKey<?>, ColumnFamily> cfamilies = readColumnFamily(Arrays.asList(command),
consistencyLevel);
         ColumnFamily cf = cfamilies.get(StorageService.getPartitioner().decorateKey(command.key));
@@ -302,7 +290,7 @@ public class CassandraServer implements 
         GenericArray<ByteBuffer> keys = new GenericData.Array<ByteBuffer>(1,
bytesArray);
         keys.add(key);
         
-        return multigetSliceInternal(curKeyspace.get(), keys, columnParent, predicate, consistencyLevel).iterator().next().columns;
+        return multigetSliceInternal(clientState.getKeyspace(), keys, columnParent, predicate,
consistencyLevel).iterator().next().columns;
     }
     
     private GenericArray<CoscsMapEntry> multigetSliceInternal(String keyspace, GenericArray<ByteBuffer>
keys,
@@ -379,7 +367,7 @@ public class CassandraServer implements 
         if (logger.isDebugEnabled())
             logger.debug("multiget_slice");
         
-        return multigetSliceInternal(curKeyspace.get(), keys, columnParent, predicate, consistencyLevel);
+        return multigetSliceInternal(clientState.getKeyspace(), keys, columnParent, predicate,
consistencyLevel);
     }
 
     @Override
@@ -390,10 +378,10 @@ public class CassandraServer implements 
             logger.debug("insert");
 
         AvroValidation.validateKey(key.array());
-        AvroValidation.validateColumnParent(curKeyspace.get(), parent);
-        AvroValidation.validateColumn(curKeyspace.get(), parent, column);
+        AvroValidation.validateColumnParent(clientState.getKeyspace(), parent);
+        AvroValidation.validateColumn(clientState.getKeyspace(), parent, column);
 
-        RowMutation rm = new RowMutation(curKeyspace.get(), key.array());
+        RowMutation rm = new RowMutation(clientState.getKeyspace(), key.array());
         try
         {
             rm.add(new QueryPath(parent.column_family.toString(),
@@ -420,10 +408,10 @@ public class CassandraServer implements 
             logger.debug("remove");
         
         AvroValidation.validateKey(key.array());
-        AvroValidation.validateColumnPath(curKeyspace.get(), columnPath);
+        AvroValidation.validateColumnPath(clientState.getKeyspace(), columnPath);
         IClock dbClock = AvroValidation.validateClock(clock);
         
-        RowMutation rm = new RowMutation(curKeyspace.get(), key.array());
+        RowMutation rm = new RowMutation(clientState.getKeyspace(), key.array());
         byte[] superName = columnPath.super_column == null ? null : columnPath.super_column.array();
         rm.delete(new QueryPath(columnPath.column_family.toString(), superName), dbClock);
         
@@ -472,9 +460,9 @@ public class CassandraServer implements 
                 String cfName = cfMutations.getKey().toString();
                 
                 for (Mutation mutation : cfMutations.getValue())
-                    AvroValidation.validateMutation(curKeyspace.get(), cfName, mutation);
+                    AvroValidation.validateMutation(clientState.getKeyspace(), cfName, mutation);
             }
-            rowMutations.add(getRowMutationFromMutations(curKeyspace.get(), pair.key.array(),
cfToMutations));
+            rowMutations.add(getRowMutationFromMutations(clientState.getKeyspace(), pair.key.array(),
cfToMutations));
         }
         
         try
@@ -624,16 +612,7 @@ public class CassandraServer implements 
             throw newInvalidRequestException("Keyspace does not exist");
         }
         
-        // If switching, invalidate previous access level; force a new login.
-        if (this.curKeyspace.get() != null && !this.curKeyspace.get().equals(keyspaceStr))
-            loginDone.set(AccessLevel.NONE);
-        
-        this.curKeyspace.set(keyspaceStr);
-
-        if (DatabaseDescriptor.getRequestSchedulerId().equals(Config.RequestSchedulerId.keyspace))
{
-            requestSchedulerId.set(curKeyspace.get());
-        }
-
+        clientState.setKeyspace(keyspaceStr);
         return null;
     }
 
@@ -784,20 +763,16 @@ public class CassandraServer implements 
         logger.debug("checking schema agreement");      
         return StorageProxy.checkSchemaAgreement();
     }
-    
+
     protected void checkKeyspaceAndLoginAuthorized(AccessLevel level) throws InvalidRequestException
     {
-        if (curKeyspace.get() == null)
+        try
         {
-            throw newInvalidRequestException("You have not assigned a keyspace; please use
set_keyspace (and login if necessary)");
+            clientState.hasKeyspaceAccess(level);
         }
-        
-        if (!(DatabaseDescriptor.getAuthenticator() instanceof AllowAllAuthenticator))
+        catch (org.apache.cassandra.thrift.InvalidRequestException e)
         {
-            if (loginDone.get() == null)
-                throw newInvalidRequestException("You have not logged into keyspace " + curKeyspace.get());
-            if (loginDone.get().compareTo(level) < 0)
-                throw newInvalidRequestException("Your credentials are not sufficient to
perform " + level + " operations");
+            throw newInvalidRequestException(e.getWhy());
         }
     }
 
@@ -806,7 +781,7 @@ public class CassandraServer implements 
      */
     private void schedule()
     {
-        requestScheduler.queue(Thread.currentThread(), requestSchedulerId.get());
+        requestScheduler.queue(Thread.currentThread(), clientState.getSchedulingId());
     }
 
     /**
@@ -916,7 +891,7 @@ public class CassandraServer implements 
         
         try
         {
-            applyMigrationOnStage(new RenameColumnFamily(curKeyspace.get(), old_name.toString(),
new_name.toString()));
+            applyMigrationOnStage(new RenameColumnFamily(clientState.getKeyspace(), old_name.toString(),
new_name.toString()));
             return DatabaseDescriptor.getDefsVersion().toString();
         }
         catch (ConfigurationException e)
@@ -940,7 +915,7 @@ public class CassandraServer implements 
         
         try
         {
-            applyMigrationOnStage(new DropColumnFamily(curKeyspace.get(), column_family.toString(),
true));
+            applyMigrationOnStage(new DropColumnFamily(clientState.getKeyspace(), column_family.toString(),
true));
             return DatabaseDescriptor.getDefsVersion().toString();
         }
         catch (ConfigurationException e)

Added: cassandra/trunk/src/java/org/apache/cassandra/service/ClientState.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/service/ClientState.java?rev=989365&view=auto
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/service/ClientState.java (added)
+++ cassandra/trunk/src/java/org/apache/cassandra/service/ClientState.java Wed Aug 25 20:41:37
2010
@@ -0,0 +1,122 @@
+/**
+ * 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.service;
+
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.cassandra.auth.AuthenticatedUser;
+import org.apache.cassandra.config.Config.RequestSchedulerId;
+import org.apache.cassandra.config.DatabaseDescriptor;
+import org.apache.cassandra.thrift.AccessLevel;
+import org.apache.cassandra.thrift.AuthenticationException;
+import org.apache.cassandra.thrift.InvalidRequestException;
+
+/**
+ * A container for per-client, thread-local state that Avro/Thrift threads must hold.
+ * TODO: Kill thrift exceptions
+ */
+public class ClientState
+{
+    private static Logger logger = LoggerFactory.getLogger(ClientState.class);
+    
+    // true if the keyspace should be used as the scheduling id
+    private final boolean SCHEDULE_ON_KEYSPACE = DatabaseDescriptor.getRequestSchedulerId().equals(RequestSchedulerId.keyspace);
+
+    // Current user for the session
+    private final ThreadLocal<AuthenticatedUser> user = new ThreadLocal<AuthenticatedUser>()
+    {
+        @Override
+        public AuthenticatedUser initialValue()
+        {
+            return DatabaseDescriptor.getAuthenticator().defaultUser();
+        }
+    };
+
+    // Keyspace and keyspace AccessLevels associated with the session
+    private final ThreadLocal<String> keyspace = new ThreadLocal<String>();
+    private final ThreadLocal<AccessLevel> keyspaceAccess = new ThreadLocal<AccessLevel>();
+
+    /**
+     * Called when the keyspace or user have changed.
+     */
+    private void updateKeyspaceAccess()
+    {
+        if (user.get() == null || keyspace.get() == null)
+            // user is not logged in or keyspace is not set
+            keyspaceAccess.set(null);
+        else
+            // authorize the user for the current keyspace
+            keyspaceAccess.set(DatabaseDescriptor.getAuthority().authorize(user.get(), keyspace.get()));
+    }
+
+    public String getKeyspace()
+    {
+        return keyspace.get();
+    }
+
+    public void setKeyspace(String ks)
+    {
+        keyspace.set(ks);
+        updateKeyspaceAccess();
+    }
+
+    public String getSchedulingId()
+    {
+        if (SCHEDULE_ON_KEYSPACE)
+            return keyspace.get();
+        return "default";
+    }
+
+    /**
+     * Attempts to login this client with the given credentials map.
+     */
+    public void login(Map<String,String> credentials) throws AuthenticationException
+    {
+        AuthenticatedUser user = DatabaseDescriptor.getAuthenticator().authenticate(credentials);
+        if (logger.isDebugEnabled())
+            logger.debug("logged in: {}", user);
+        this.user.set(user);
+        updateKeyspaceAccess();
+    }
+
+    public void logout()
+    {
+        if (logger.isDebugEnabled())
+            logger.debug("logged out: {}", user.get());
+        user.remove();
+        keyspace.remove();
+        keyspaceAccess.remove();
+    }
+
+    /**
+     * Confirms that the client thread has the given AccessLevel in the context of the current
Keyspace.
+     */
+    public void hasKeyspaceAccess(AccessLevel level) throws InvalidRequestException
+    {
+        if (user.get() == null)
+            throw new InvalidRequestException("You have not logged in");
+        if (keyspaceAccess.get() == null)
+            throw new InvalidRequestException("You have not set a keyspace for this session");
+        if (keyspaceAccess.get().ordinal() < level.ordinal())
+            throw new InvalidRequestException(String.format("Your user (%s) does not have
permission to perform %s operations", user, level));
+    }
+}

Modified: cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraDaemon.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraDaemon.java?rev=989365&r1=989364&r2=989365&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraDaemon.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraDaemon.java Wed Aug 25 20:41:37
2010
@@ -194,7 +194,7 @@ public class CassandraDaemon extends org
             protected void afterExecute(Runnable r, Throwable t)
             {
                 super.afterExecute(r, t);
-                cassandraServer.logout();
+                cassandraServer.clientState.logout();
             }
         };
         serverEngine = new CustomTThreadPoolServer(new TProcessorFactory(processor),

Modified: cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java
URL: http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java?rev=989365&r1=989364&r2=989365&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/thrift/CassandraServer.java Wed Aug 25 20:41:37
2010
@@ -54,6 +54,7 @@ import org.apache.cassandra.dht.IPartiti
 import org.apache.cassandra.dht.Range;
 import org.apache.cassandra.dht.Token;
 import org.apache.cassandra.scheduler.IRequestScheduler;
+import org.apache.cassandra.service.ClientState;
 import org.apache.cassandra.service.StorageProxy;
 import org.apache.cassandra.service.StorageService;
 import org.apache.thrift.TException;
@@ -66,24 +67,8 @@ public class CassandraServer implements 
     private final static List<ColumnOrSuperColumn> EMPTY_COLUMNS = Collections.emptyList();
     private final static List<Column> EMPTY_SUBCOLUMNS = Collections.emptyList();
 
-    // will be set only by login()
-    private ThreadLocal<AuthenticatedUser> loginDone = new ThreadLocal<AuthenticatedUser>()
{
-        @Override
-        public AuthenticatedUser initialValue()
-        {
-            return DatabaseDescriptor.getAuthenticator().defaultUser();
-        }
-    };
-
-    /*
-     * Keyspace associated with session
-     */
-    private ThreadLocal<String> keySpace = new ThreadLocal<String>();
-
-    /*
-     * An associated Id for scheduling the requests
-     */
-    private ThreadLocal<String> requestSchedulerId = new ThreadLocal<String>();
+    // thread local state containing session information
+    public final ClientState clientState = new ClientState();
 
     /*
      * RequestScheduler to perform the scheduling of incoming requests
@@ -267,8 +252,8 @@ public class CassandraServer implements 
         if (logger.isDebugEnabled())
             logger.debug("get_slice");
         
-        checkKeyspaceAndLoginAuthorized(AccessLevel.READONLY);
-        return multigetSliceInternal(keySpace.get(), Arrays.asList(key), column_parent, predicate,
consistency_level).get(key);
+        clientState.hasKeyspaceAccess(AccessLevel.READONLY);
+        return multigetSliceInternal(clientState.getKeyspace(), Arrays.asList(key), column_parent,
predicate, consistency_level).get(key);
     }
     
     public Map<byte[], List<ColumnOrSuperColumn>> multiget_slice(List<byte[]>
keys, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level)
@@ -277,9 +262,9 @@ public class CassandraServer implements 
         if (logger.isDebugEnabled())
             logger.debug("multiget_slice");
 
-        checkKeyspaceAndLoginAuthorized(AccessLevel.READONLY);
+        clientState.hasKeyspaceAccess(AccessLevel.READONLY);
 
-        return multigetSliceInternal(keySpace.get(), keys, column_parent, predicate, consistency_level);
+        return multigetSliceInternal(clientState.getKeyspace(), keys, column_parent, predicate,
consistency_level);
     }
 
     private Map<byte[], List<ColumnOrSuperColumn>> multigetSliceInternal(String
keyspace, List<byte[]> keys, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel
consistency_level)
@@ -316,8 +301,8 @@ public class CassandraServer implements 
         if (logger.isDebugEnabled())
             logger.debug("get");
 
-        checkKeyspaceAndLoginAuthorized(AccessLevel.READONLY);
-        String keyspace = keySpace.get();
+        clientState.hasKeyspaceAccess(AccessLevel.READONLY);
+        String keyspace = clientState.getKeyspace();
 
         ThriftValidation.validateColumnPath(keyspace, column_path);
 
@@ -344,7 +329,7 @@ public class CassandraServer implements 
         if (logger.isDebugEnabled())
             logger.debug("get_count");
 
-        checkKeyspaceAndLoginAuthorized(AccessLevel.READONLY);
+        clientState.hasKeyspaceAccess(AccessLevel.READONLY);
 
         return get_slice(key, column_parent, predicate, consistency_level).size();
     }
@@ -355,8 +340,8 @@ public class CassandraServer implements 
         if (logger.isDebugEnabled())
             logger.debug("multiget_count");
 
-        checkKeyspaceAndLoginAuthorized(AccessLevel.READONLY);
-        String keyspace = keySpace.get();
+        clientState.hasKeyspaceAccess(AccessLevel.READONLY);
+        String keyspace = clientState.getKeyspace();
 
         Map<byte[], Integer> counts = new HashMap<byte[], Integer>();
         Map<byte[], List<ColumnOrSuperColumn>> columnFamiliesMap = multigetSliceInternal(keyspace,
keys, column_parent, predicate, consistency_level);
@@ -373,14 +358,14 @@ public class CassandraServer implements 
         if (logger.isDebugEnabled())
             logger.debug("insert");
 
-        checkKeyspaceAndLoginAuthorized(AccessLevel.READWRITE);
+        clientState.hasKeyspaceAccess(AccessLevel.READWRITE);
 
         ThriftValidation.validateKey(key);
-        ThriftValidation.validateColumnParent(keySpace.get(), column_parent);
-        ThriftValidation.validateColumn(keySpace.get(), column_parent, column);
+        ThriftValidation.validateColumnParent(clientState.getKeyspace(), column_parent);
+        ThriftValidation.validateColumn(clientState.getKeyspace(), column_parent, column);
         IClock cassandra_clock = ThriftValidation.validateClock(column.clock);
 
-        RowMutation rm = new RowMutation(keySpace.get(), key);
+        RowMutation rm = new RowMutation(clientState.getKeyspace(), key);
         try
         {
             rm.add(new QueryPath(column_parent.column_family, column_parent.super_column,
column.name), column.value, cassandra_clock, column.ttl);
@@ -416,7 +401,7 @@ public class CassandraServer implements 
             }
         }
         
-        checkKeyspaceAndLoginAuthorized(needed);
+        clientState.hasKeyspaceAccess(needed);
 
         List<RowMutation> rowMutations = new ArrayList<RowMutation>();
         for (Map.Entry<byte[], Map<String, List<Mutation>>> mutationEntry:
mutation_map.entrySet())
@@ -431,10 +416,10 @@ public class CassandraServer implements 
 
                 for (Mutation mutation : columnFamilyMutations.getValue())
                 {
-                    ThriftValidation.validateMutation(keySpace.get(), cfName, mutation);
+                    ThriftValidation.validateMutation(clientState.getKeyspace(), cfName,
mutation);
                 }
             }
-            rowMutations.add(RowMutation.getRowMutationFromMutations(keySpace.get(), key,
columnFamilyToMutations));
+            rowMutations.add(RowMutation.getRowMutationFromMutations(clientState.getKeyspace(),
key, columnFamilyToMutations));
         }
 
         doInsert(consistency_level, rowMutations);
@@ -446,14 +431,14 @@ public class CassandraServer implements 
         if (logger.isDebugEnabled())
             logger.debug("remove");
 
-        checkKeyspaceAndLoginAuthorized(AccessLevel.FULL);
+        clientState.hasKeyspaceAccess(AccessLevel.FULL);
 
         ThriftValidation.validateKey(key);
-        ThriftValidation.validateColumnPathOrParent(keySpace.get(), column_path);
+        ThriftValidation.validateColumnPathOrParent(clientState.getKeyspace(), column_path);
 
         IClock cassandra_clock = ThriftValidation.validateClock(clock);
 
-        RowMutation rm = new RowMutation(keySpace.get(), key);
+        RowMutation rm = new RowMutation(clientState.getKeyspace(), key);
         rm.delete(new QueryPath(column_path), cassandra_clock);
 
         doInsert(consistency_level, Arrays.asList(rm));
@@ -518,8 +503,8 @@ public class CassandraServer implements 
         if (logger.isDebugEnabled())
             logger.debug("range_slice");
 
-        String keyspace = keySpace.get();
-        checkKeyspaceAndLoginAuthorized(AccessLevel.READONLY);
+        String keyspace = clientState.getKeyspace();
+        clientState.hasKeyspaceAccess(AccessLevel.READONLY);
 
         ThriftValidation.validateColumnParent(keyspace, column_parent);
         ThriftValidation.validatePredicate(keyspace, column_parent, predicate);
@@ -582,8 +567,8 @@ public class CassandraServer implements 
         if (logger.isDebugEnabled())
             logger.debug("scan");
 
-        checkKeyspaceAndLoginAuthorized(AccessLevel.READONLY);
-        String keyspace = keySpace.get();
+        clientState.hasKeyspaceAccess(AccessLevel.READONLY);
+        String keyspace = clientState.getKeyspace();
         ThriftValidation.validateColumnParent(keyspace, column_parent);
         ThriftValidation.validatePredicate(keyspace, column_parent, column_predicate);
         ThriftValidation.validateIndexClauses(keyspace, column_parent.column_family, index_clause);
@@ -663,30 +648,7 @@ public class CassandraServer implements 
 
     public void login(AuthenticationRequest auth_request) throws AuthenticationException,
AuthorizationException, TException
     {
-        AuthenticatedUser user = DatabaseDescriptor.getAuthenticator().authenticate(auth_request.getCredentials());
-        
-        if (logger.isDebugEnabled())
-            logger.debug("login confirmed; user is " + user);
-        
-        loginDone.set(user);
-    }
-
-    public void logout()
-    {
-        keySpace.remove();
-        loginDone.remove();
-
-        if (logger.isDebugEnabled())
-            logger.debug("logout complete");
-    }
-
-    protected void checkKeyspaceAndLoginAuthorized(AccessLevel level) throws InvalidRequestException
-    {
-        if (loginDone.get() == null)
-            throw new InvalidRequestException("You have not logged in");
-
-        // FIXME: if no keyspace set, check against global authlist. otherwise, check
-        // against keyspace authlist
+         clientState.login(auth_request.getCredentials());
     }
 
     /**
@@ -694,7 +656,7 @@ public class CassandraServer implements 
      */
     private void schedule()
     {
-        requestScheduler.queue(Thread.currentThread(), requestSchedulerId.get());
+        requestScheduler.queue(Thread.currentThread(), clientState.getSchedulingId());
     }
 
     /**
@@ -746,7 +708,7 @@ public class CassandraServer implements 
 
     public String system_add_column_family(CfDef cf_def) throws InvalidRequestException,
TException
     {
-        checkKeyspaceAndLoginAuthorized(AccessLevel.FULL);
+        clientState.hasKeyspaceAccess(AccessLevel.FULL);
         try
         {
             applyMigrationOnStage(new AddColumnFamily(convertToCFMetaData(cf_def)));
@@ -768,11 +730,11 @@ public class CassandraServer implements 
 
     public String system_drop_column_family(String column_family) throws InvalidRequestException,
TException
     {
-        checkKeyspaceAndLoginAuthorized(AccessLevel.FULL);
+        clientState.hasKeyspaceAccess(AccessLevel.FULL);
         
         try
         {
-            applyMigrationOnStage(new DropColumnFamily(keySpace.get(), column_family, true));
+            applyMigrationOnStage(new DropColumnFamily(clientState.getKeyspace(), column_family,
true));
             return DatabaseDescriptor.getDefsVersion().toString();
         }
         catch (ConfigurationException e)
@@ -791,11 +753,11 @@ public class CassandraServer implements 
 
     public String system_rename_column_family(String old_name, String new_name) throws InvalidRequestException,
TException
     {
-        checkKeyspaceAndLoginAuthorized(AccessLevel.FULL);
+        clientState.hasKeyspaceAccess(AccessLevel.FULL);
         
         try
         {
-            applyMigrationOnStage(new RenameColumnFamily(keySpace.get(), old_name, new_name));
+            applyMigrationOnStage(new RenameColumnFamily(clientState.getKeyspace(), old_name,
new_name));
             return DatabaseDescriptor.getDefsVersion().toString();
         }
         catch (ConfigurationException e)
@@ -899,7 +861,7 @@ public class CassandraServer implements 
 
     public String system_rename_keyspace(String old_name, String new_name) throws InvalidRequestException,
TException
     {
-        checkKeyspaceAndLoginAuthorized(AccessLevel.FULL);
+        clientState.hasKeyspaceAccess(AccessLevel.FULL);
         
         try
         {
@@ -961,12 +923,12 @@ public class CassandraServer implements 
 
     public void truncate(String cfname) throws InvalidRequestException, UnavailableException,
TException
     {
-        logger.debug("truncating {} in {}", cfname, keySpace.get());
-        checkKeyspaceAndLoginAuthorized(AccessLevel.FULL);
+        logger.debug("truncating {} in {}", cfname, clientState.getKeyspace());
+        clientState.hasKeyspaceAccess(AccessLevel.READWRITE);
         try
         {
             schedule();
-            StorageProxy.truncateBlocking(keySpace.get(), cfname);
+            StorageProxy.truncateBlocking(clientState.getKeyspace(), cfname);
         }
         catch (TimeoutException e)
         {
@@ -989,8 +951,7 @@ public class CassandraServer implements 
             throw new InvalidRequestException("Keyspace does not exist");
         }
         
-        keySpace.set(keyspace);
-        requestSchedulerId.set(keyspace);
+        clientState.setKeyspace(keyspace);
     }
 
     public Map<String, List<String>> check_schema_agreement() throws TException,
InvalidRequestException



Mime
View raw message