You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by al...@apache.org on 2014/05/29 21:57:50 UTC
git commit: Add conditional CREATE/DROP USER support
Repository: cassandra
Updated Branches:
refs/heads/cassandra-2.0 6574de534 -> 7216639e5
Add conditional CREATE/DROP USER support
patch by Aleksey Yeschenko; reviewed by Tyler Hobbs for CASSANDRA-7264
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/7216639e
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/7216639e
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/7216639e
Branch: refs/heads/cassandra-2.0
Commit: 7216639e512c2f5d4834bd5213d7e30af68aefa3
Parents: 6574de5
Author: Aleksey Yeschenko <al...@apache.org>
Authored: Thu May 29 22:55:38 2014 +0300
Committer: Aleksey Yeschenko <al...@apache.org>
Committed: Thu May 29 22:55:38 2014 +0300
----------------------------------------------------------------------
CHANGES.txt | 1 +
doc/cql3/CQL.textile | 1 +
src/java/org/apache/cassandra/cql3/Cql.g | 12 +++++++-----
.../cassandra/cql3/statements/CreateUserStatement.java | 10 ++++++++--
.../cassandra/cql3/statements/DropUserStatement.java | 10 ++++++++--
5 files changed, 25 insertions(+), 9 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/7216639e/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 98a0a33..28c2ad6 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
2.0.9
+ * Add conditional CREATE/DROP USER support (CASSANDRA-7264)
* Swap local and global default read repair chances (CASSANDRA-7320)
* Add missing iso8601 patterns for date strings (CASSANDRA-6973)
* Support selecting multiple rows in a partition using IN (CASSANDRA-6875)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/7216639e/doc/cql3/CQL.textile
----------------------------------------------------------------------
diff --git a/doc/cql3/CQL.textile b/doc/cql3/CQL.textile
index 393dc0d..f53448e 100644
--- a/doc/cql3/CQL.textile
+++ b/doc/cql3/CQL.textile
@@ -1173,6 +1173,7 @@ The following describes the addition/changes brought for each version of CQL.
h3. 3.1.7
* @SELECT@ statements now support selecting multiple rows in a single partition using an @IN@ clause on combinations of clustering columns. See "SELECT WHERE":#selectWhere clauses.
+* @IF NOT EXISTS@ and @IF EXISTS@ syntax is now supported by @CREATE USER@ and @DROP USER@ statmenets, respectively.
h3. 3.1.6
http://git-wip-us.apache.org/repos/asf/cassandra/blob/7216639e/src/java/org/apache/cassandra/cql3/Cql.g
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/Cql.g b/src/java/org/apache/cassandra/cql3/Cql.g
index ceb2bde..06dbc3a 100644
--- a/src/java/org/apache/cassandra/cql3/Cql.g
+++ b/src/java/org/apache/cassandra/cql3/Cql.g
@@ -687,17 +687,18 @@ dataResource returns [DataResource res]
;
/**
- * CREATE USER <username> [WITH PASSWORD <password>] [SUPERUSER|NOSUPERUSER]
+ * CREATE USER [IF NOT EXISTS] <username> [WITH PASSWORD <password>] [SUPERUSER|NOSUPERUSER]
*/
createUserStatement returns [CreateUserStatement stmt]
@init {
UserOptions opts = new UserOptions();
boolean superuser = false;
+ boolean ifNotExists = false;
}
- : K_CREATE K_USER username
+ : K_CREATE K_USER (K_IF K_NOT K_EXISTS { ifNotExists = true; })? username
( K_WITH userOptions[opts] )?
( K_SUPERUSER { superuser = true; } | K_NOSUPERUSER { superuser = false; } )?
- { $stmt = new CreateUserStatement($username.text, opts, superuser); }
+ { $stmt = new CreateUserStatement($username.text, opts, superuser, ifNotExists); }
;
/**
@@ -715,10 +716,11 @@ alterUserStatement returns [AlterUserStatement stmt]
;
/**
- * DROP USER <username>
+ * DROP USER [IF EXISTS] <username>
*/
dropUserStatement returns [DropUserStatement stmt]
- : K_DROP K_USER username { $stmt = new DropUserStatement($username.text); }
+ @init { boolean ifExists = false; }
+ : K_DROP K_USER (K_IF K_EXISTS { ifExists = true; })? username { $stmt = new DropUserStatement($username.text, ifExists); }
;
/**
http://git-wip-us.apache.org/repos/asf/cassandra/blob/7216639e/src/java/org/apache/cassandra/cql3/statements/CreateUserStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateUserStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateUserStatement.java
index a82b38d..0903659 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateUserStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateUserStatement.java
@@ -32,12 +32,14 @@ public class CreateUserStatement extends AuthenticationStatement
private final String username;
private final UserOptions opts;
private final boolean superuser;
+ private final boolean ifNotExists;
- public CreateUserStatement(String username, UserOptions opts, boolean superuser)
+ public CreateUserStatement(String username, UserOptions opts, boolean superuser, boolean ifNotExists)
{
this.username = username;
this.opts = opts;
this.superuser = superuser;
+ this.ifNotExists = ifNotExists;
}
public void validate(ClientState state) throws RequestValidationException
@@ -50,7 +52,7 @@ public class CreateUserStatement extends AuthenticationStatement
// validate login here before checkAccess to avoid leaking user existence to anonymous users.
state.ensureNotAnonymous();
- if (Auth.isExistingUser(username))
+ if (!ifNotExists && Auth.isExistingUser(username))
throw new InvalidRequestException(String.format("User %s already exists", username));
}
@@ -62,6 +64,10 @@ public class CreateUserStatement extends AuthenticationStatement
public ResultMessage execute(ClientState state) throws RequestValidationException, RequestExecutionException
{
+ // not rejected in validate()
+ if (ifNotExists && Auth.isExistingUser(username))
+ return null;
+
DatabaseDescriptor.getAuthenticator().create(username, opts.getOptions());
Auth.insertUser(username, superuser);
return null;
http://git-wip-us.apache.org/repos/asf/cassandra/blob/7216639e/src/java/org/apache/cassandra/cql3/statements/DropUserStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/DropUserStatement.java b/src/java/org/apache/cassandra/cql3/statements/DropUserStatement.java
index 0894db0..9e92b26 100644
--- a/src/java/org/apache/cassandra/cql3/statements/DropUserStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/DropUserStatement.java
@@ -30,10 +30,12 @@ import org.apache.cassandra.transport.messages.ResultMessage;
public class DropUserStatement extends AuthenticationStatement
{
private final String username;
+ private final boolean ifExists;
- public DropUserStatement(String username)
+ public DropUserStatement(String username, boolean ifExists)
{
this.username = username;
+ this.ifExists = ifExists;
}
public void validate(ClientState state) throws RequestValidationException
@@ -41,7 +43,7 @@ public class DropUserStatement extends AuthenticationStatement
// validate login here before checkAccess to avoid leaking user existence to anonymous users.
state.ensureNotAnonymous();
- if (!Auth.isExistingUser(username))
+ if (!ifExists && !Auth.isExistingUser(username))
throw new InvalidRequestException(String.format("User %s doesn't exist", username));
AuthenticatedUser user = state.getUser();
@@ -57,6 +59,10 @@ public class DropUserStatement extends AuthenticationStatement
public ResultMessage execute(ClientState state) throws RequestValidationException, RequestExecutionException
{
+ // not rejected in validate()
+ if (ifExists && !Auth.isExistingUser(username))
+ return null;
+
// clean up permissions after the dropped user.
DatabaseDescriptor.getAuthorizer().revokeAll(username);
Auth.deleteUser(username);