Merge branch 'cassandra-3.0' into cassandra-3.X

Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/9be467a2
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/9be467a2
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/9be467a2

Branch: refs/heads/trunk
Commit: 9be467a22ab646c23710eb2b23dd21e5a46b07bd
Parents: 49ce0a4 e4f840a
Author: Sam Tunnicliffe <s...@beobal.com>
Authored: Fri Oct 28 16:11:13 2016 +0100
Committer: Sam Tunnicliffe <s...@beobal.com>
Committed: Fri Oct 28 16:17:52 2016 +0100

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../cassandra/auth/CassandraAuthorizer.java     | 13 ++++--
 .../cassandra/auth/PasswordAuthenticator.java   | 42 ++++++++++++++------
 3 files changed, 41 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/9be467a2/CHANGES.txt
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/9be467a2/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
index 8c3485d,7ffef27..7f44eef
--- a/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
+++ b/src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
@@@ -215,12 -209,20 +215,19 @@@ public class CassandraAuthorizer implem
                                                               
Lists.newArrayList(ByteBufferUtil.bytes(role.getRoleName()),
                                                                                
  ByteBufferUtil.bytes(resource.getName())));
  
+         SelectStatement statement;
          // If it exists, read from the legacy user permissions table to 
handle the case where the cluster
          // is being upgraded and so is running with mixed versions of the 
authz schema
-         SelectStatement statement = 
Schema.instance.getCFMetaData(SchemaConstants.AUTH_KEYSPACE_NAME, 
USER_PERMISSIONS) == null
-                                     ? authorizeRoleStatement
-                                     : legacyAuthorizeRoleStatement;
 -        if (Schema.instance.getCFMetaData(AuthKeyspace.NAME, 
USER_PERMISSIONS) == null)
++        if (Schema.instance.getCFMetaData(SchemaConstants.AUTH_KEYSPACE_NAME, 
USER_PERMISSIONS) == null)
+             statement = authorizeRoleStatement;
+         else
+         {
+             // If the permissions table was initialised only after the 
statement got prepared, re-prepare (CASSANDRA-12813)
+             if (legacyAuthorizeRoleStatement == null)
+                 legacyAuthorizeRoleStatement = prepare(USERNAME, 
USER_PERMISSIONS);
+             statement = legacyAuthorizeRoleStatement;
+         }
 -
 -        ResultMessage.Rows rows = 
statement.execute(QueryState.forInternalCalls(), options) ;
 +        ResultMessage.Rows rows = 
statement.execute(QueryState.forInternalCalls(), options, System.nanoTime());
          UntypedResultSet result = UntypedResultSet.create(rows.result);
  
          if (!result.isEmpty() && result.one().has(PERMISSIONS))

http://git-wip-us.apache.org/repos/asf/cassandra/blob/9be467a2/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
index b0317f3,ca610d1..4b667ae
--- a/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
+++ b/src/java/org/apache/cassandra/auth/PasswordAuthenticator.java
@@@ -86,56 -78,8 +86,52 @@@ public class PasswordAuthenticator impl
      {
          try
          {
 +            String hash = cache.get(username);
 +            if (!BCrypt.checkpw(password, hash))
 +                throw new AuthenticationException(String.format("Provided 
username %s and/or password are incorrect", username));
 +
 +            return new AuthenticatedUser(username);
 +        }
 +        catch (ExecutionException | UncheckedExecutionException e)
 +        {
 +            // the credentials were somehow invalid - either a non-existent 
role, or one without a defined password
 +            if (e.getCause() instanceof NoSuchCredentialsException)
 +                throw new AuthenticationException(String.format("Provided 
username %s and/or password are incorrect", username));
 +
 +            // an unanticipated exception occured whilst querying the 
credentials table
 +            if (e.getCause() instanceof RequestExecutionException)
 +            {
 +                logger.trace("Error performing internal authentication", e);
 +                throw new AuthenticationException(String.format("Error during 
authentication of user %s : %s", username, e.getMessage()));
 +            }
 +
 +            throw new RuntimeException(e);
 +        }
 +    }
 +
 +    private String queryHashedPassword(String username) throws 
NoSuchCredentialsException
 +    {
 +        try
 +        {
-             // If the legacy users table exists try to verify credentials 
there. This is to handle the case
-             // where the cluster is being upgraded and so is running with 
mixed versions of the authn tables
-             SelectStatement authenticationStatement = 
Schema.instance.getCFMetaData(SchemaConstants.AUTH_KEYSPACE_NAME, 
LEGACY_CREDENTIALS_TABLE) == null
-                                                     ? authenticateStatement
-                                                     : 
legacyAuthenticateStatement;
+             SelectStatement authenticationStatement = 
authenticationStatement();
 -            return doAuthenticate(username, password, 
authenticationStatement);
 +
 +            ResultMessage.Rows rows =
 +                authenticationStatement.execute(QueryState.forInternalCalls(),
 +                                                
QueryOptions.forInternalCalls(consistencyForRole(username),
 +                                                                              
Lists.newArrayList(ByteBufferUtil.bytes(username))),
 +                                                System.nanoTime());
 +
 +            // If either a non-existent role name was supplied, or no 
credentials
 +            // were found for that role we don't want to cache the result so 
we throw
 +            // a specific, but unchecked, exception to keep LoadingCache 
happy.
 +            if (rows.result.isEmpty())
 +                throw new NoSuchCredentialsException();
 +
 +            UntypedResultSet result = UntypedResultSet.create(rows.result);
 +            if (!result.one().has(SALTED_HASH))
 +                throw new NoSuchCredentialsException();
 +
 +            return result.one().getString(SALTED_HASH);
          }
          catch (RequestExecutionException e)
          {
@@@ -144,6 -88,23 +140,25 @@@
          }
      }
  
+     /**
+      * If the legacy users table exists try to verify credentials there. This 
is to handle the case
+      * where the cluster is being upgraded and so is running with mixed 
versions of the authn tables
+      */
+     private SelectStatement authenticationStatement()
+     {
 -        if (Schema.instance.getCFMetaData(AuthKeyspace.NAME, 
LEGACY_CREDENTIALS_TABLE) == null)
++        if (Schema.instance.getCFMetaData(SchemaConstants.AUTH_KEYSPACE_NAME, 
LEGACY_CREDENTIALS_TABLE) == null)
+             return authenticateStatement;
+         else
+         {
++            // the statement got prepared, we to try preparing it again.
+             // If the credentials was initialised only after statement got 
prepared, re-prepare (CASSANDRA-12813).
+             if (legacyAuthenticateStatement == null)
+                 prepareLegacyAuthenticateStatement();
+             return legacyAuthenticateStatement;
+         }
+     }
+ 
++
      public Set<DataResource> protectedResources()
      {
          // Also protected by CassandraRoleManager, but the duplication 
doesn't hurt and is more explicit
@@@ -162,18 -123,19 +177,21 @@@
                                       AuthKeyspace.ROLES);
          authenticateStatement = prepare(query);
  
 -        if (Schema.instance.getCFMetaData(AuthKeyspace.NAME, 
LEGACY_CREDENTIALS_TABLE) != null)
 +        if (Schema.instance.getCFMetaData(SchemaConstants.AUTH_KEYSPACE_NAME, 
LEGACY_CREDENTIALS_TABLE) != null)
-         {
-             query = String.format("SELECT %s from %s.%s WHERE username = ?",
-                                   SALTED_HASH,
-                                   SchemaConstants.AUTH_KEYSPACE_NAME,
-                                   LEGACY_CREDENTIALS_TABLE);
-             legacyAuthenticateStatement = prepare(query);
-         }
+             prepareLegacyAuthenticateStatement();
 +
 +        cache = new CredentialsCache(this);
      }
  
+     private void prepareLegacyAuthenticateStatement()
+     {
+         String query = String.format("SELECT %s from %s.%s WHERE username = 
?",
+                                      SALTED_HASH,
 -                                     AuthKeyspace.NAME,
++                                     SchemaConstants.AUTH_KEYSPACE_NAME,
+                                      LEGACY_CREDENTIALS_TABLE);
+         legacyAuthenticateStatement = prepare(query);
+     }
+ 
      public AuthenticatedUser legacyAuthenticate(Map<String, String> 
credentials) throws AuthenticationException
      {
          String username = credentials.get(USERNAME_KEY);

Reply via email to