You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by da...@apache.org on 2007/10/15 13:24:16 UTC
svn commit: r584738 - in /db/derby/code/trunk/java:
engine/org/apache/derby/iapi/sql/ engine/org/apache/derby/iapi/sql/compile/
engine/org/apache/derby/impl/sql/compile/
testing/org/apache/derbyTesting/functionTests/tests/lang/
Author: dag
Date: Mon Oct 15 04:24:15 2007
New Revision: 584738
URL: http://svn.apache.org/viewvc?rev=584738&view=rev
Log:
DERBY-3073 SQL roles: add parser support
Patch DERBY-3073c. This patch adds support for roles to the parser, plus tests for the
new syntax.
Added:
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/RolesTest.java (with props)
Modified:
db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/StatementType.java
db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/C_NodeTypes.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/NodeFactoryImpl.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java
Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/StatementType.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/StatementType.java?rev=584738&r1=584737&r2=584738&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/StatementType.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/StatementType.java Mon Oct 15 04:24:15 2007
@@ -51,7 +51,8 @@
public static final int SET_SCHEMA_USER = 1;
public static final int SET_SCHEMA_DYNAMIC = 2;
-
+
+ public static final int SET_ROLE_DYNAMIC = 1;
}
Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/C_NodeTypes.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/C_NodeTypes.java?rev=584738&r1=584737&r2=584738&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/C_NodeTypes.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/C_NodeTypes.java Mon Oct 15 04:24:15 2007
@@ -217,6 +217,18 @@
static final int XML_EXISTS_OPERATOR_NODE = 202;
static final int XML_QUERY_OPERATOR_NODE = 203;
+ // Roles
+ static final int CURRENT_ROLE_NODE = 210;
+ static final int CREATE_ROLE_NODE = 211;
+ static final int SET_ROLE_NODE = 212;
+ static final int SET_ROLE_DYNAMIC = 213;
+ static final int DROP_ROLE_NODE = 214;
+ static final int GRANT_ROLE_NODE = 215;
+ static final int REVOKE_ROLE_NODE = 216;
+
+ // Final value in set, keep up to date!
+ static final int FINAL_VALUE = REVOKE_ROLE_NODE;
+
/**
* Extensions to this interface can use nodetypes > MAX_NODE_TYPE with out fear of collision
* with C_NodeTypes
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/NodeFactoryImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/NodeFactoryImpl.java?rev=584738&r1=584737&r2=584738&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/NodeFactoryImpl.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/NodeFactoryImpl.java Mon Oct 15 04:24:15 2007
@@ -72,7 +72,8 @@
/* Do join order optimization by default */
private Boolean joinOrderOptimization = Boolean.TRUE;
- private final ClassInfo[] nodeCi = new ClassInfo[205];
+ private final ClassInfo[] nodeCi =
+ new ClassInfo[C_NodeTypes.FINAL_VALUE+1];
private static final Vector emptyVector = new Vector(0);
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj?rev=584738&r1=584737&r2=584738&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/sqlgrammar.jj Mon Oct 15 04:24:15 2007
@@ -322,7 +322,7 @@
Utility method for checking that the underlying database uses SQL standard
permission checking (GRANT/REVOKE).
- @param command "GRANT" or "REVOKE"
+ @param command "GRANT", "REVOKE", "CREATE/DROP/SET ROLE" or CURRENT_ROLE
*/
private void checkSqlStandardAccess( String command) throws StandardException
{
@@ -1675,6 +1675,16 @@
}
}
}
+
+ boolean isPrivilegeKeywordExceptTrigger(int tokenKind) {
+ return (tokenKind == SELECT ||
+ tokenKind == DELETE ||
+ tokenKind == INSERT ||
+ tokenKind == UPDATE ||
+ tokenKind == REFERENCES ||
+ tokenKind == EXECUTE ||
+ tokenKind == ALL);
+ }
}
PARSER_END(SQLParser)
@@ -2222,6 +2232,7 @@
<BOOLEAN: "boolean">
| <CALL: "call">
| <CURDATE: "curdate">
+| <CURRENT_ROLE: "current_role">
| <CURTIME: "curtime">
| <DATABASE: "database">
| <GET_CURRENT_CONNECTION: "getCurrentConnection">
@@ -2229,6 +2240,8 @@
| <LONGINT: "bigint">
| <LONG: "long">
| <LTRIM: "ltrim">
+| <NONE: "none">
+| <ROLE: "role">
| <RTRIM: "rtrim">
| <SUBSTR: "substr">
| <XML: "xml">
@@ -2767,7 +2780,8 @@
statementNode = schemaDefinition() |
statementNode = viewDefinition(beginToken) |
statementNode = triggerDefinition() |
- statementNode = synonymDefinition()
+ statementNode = synonymDefinition() |
+ statementNode = roleDefinition()
)
{
}
@@ -2803,7 +2817,8 @@
statementNode = dropIndexStatement() |
statementNode = dropAliasStatement() |
statementNode = dropViewStatement() |
- statementNode = dropTriggerStatement()
+ statementNode = dropTriggerStatement() |
+ statementNode = dropRoleStatement()
)
{
return statementNode;
@@ -2842,7 +2857,8 @@
(
statementNode = setIsolationStatement() |
statementNode = setSchemaStatement() |
- statementNode = setMessageLocaleStatement()
+ statementNode = setMessageLocaleStatement() |
+ statementNode = setRoleStatement()
)
{
return statementNode;
@@ -7344,6 +7360,11 @@
{
return parm;
}
+|
+ parm = currentRoleNode()
+ {
+ return parm;
+ }
}
ValueNode
@@ -7374,6 +7395,23 @@
}
+/*
+ * <A NAME="currentRoleNode">currentRoleNode</A>
+ */
+ValueNode
+currentRoleNode() throws StandardException :
+{
+}
+{
+ <CURRENT_ROLE>
+ {
+ checkSqlStandardAccess("CURRENT_ROLE");
+ checkVersion( DataDictionary.DD_VERSION_DERBY_10_4, "ROLES");
+ return (ValueNode) nodeFactory.getNode(
+ C_NodeTypes.CURRENT_ROLE_NODE,
+ getContextManager());
+ }
+}
/*
@@ -9581,6 +9619,34 @@
)
}
+
+/*
+ * <A NAME="roleDefinition">roleDefinition</A>
+ */
+StatementNode
+roleDefinition() throws StandardException :
+{
+ String roleName = null;
+}
+{
+ /*
+ * CREATE ROLE
+ *
+ * Not currently supported: [ WITH ADMIN <grantor>]
+ */
+ <ROLE> roleName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true)
+ {
+ checkSqlStandardAccess("CREATE ROLE");
+ checkVersion( DataDictionary.DD_VERSION_DERBY_10_4, "ROLES");
+
+ return (StatementNode) nodeFactory.getNode(
+ C_NodeTypes.CREATE_ROLE_NODE,
+ roleName,
+ getContextManager());
+ }
+}
+
+
/*
* <A NAME="tableDefinition">tableDefinition</A>
*/
@@ -10598,6 +10664,11 @@
return value;
}
|
+ value = currentRoleNode()
+ {
+ return value;
+ }
+|
LOOKAHEAD({
getToken(1).kind == DATE ||
getToken(1).kind == TIME ||
@@ -11322,6 +11393,78 @@
}
+/*
+ * <A NAME="setRoleStatement">setRoleStatement</A>
+ */
+StatementNode
+setRoleStatement() throws StandardException :
+{
+ StatementNode role;
+}
+{
+ /*
+ * SET ROLE { <rolename> | NONE | ? }
+ *
+ * Can also be prepared with ? argument, cf. SET SCHEMA.
+ */
+ <ROLE> role = setRoleSpecification()
+ {
+ if (parameterList != null && parameterList.size() > 0)
+ {
+ setUpAndLinkParameters();
+ // set the type of parameter node, it should be a varchar
+ // max Limits.MAX_IDENTIFIER_LENGTH - non nullable
+ ParameterNode p = (ParameterNode)parameterList.elementAt(0);
+ p.setType(new DataTypeDescriptor
+ (TypeId.getBuiltInTypeId(Types.VARCHAR),
+ false,
+ Limits.MAX_IDENTIFIER_LENGTH));
+ }
+ return role;
+ }
+}
+
+
+/*
+ * <A NAME="setRoleSpecification">setRoleSpecification</A>
+ */
+StatementNode
+setRoleSpecification() throws StandardException :
+{
+ String roleName = null;
+ checkSqlStandardAccess("SET ROLE");
+ checkVersion( DataDictionary.DD_VERSION_DERBY_10_4, "ROLES");
+}
+{
+ <NONE>
+ {
+ return (StatementNode) nodeFactory.getNode
+ (C_NodeTypes.SET_ROLE_NODE,
+ roleName,
+ null,
+ getContextManager());
+ }
+|
+ roleName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true)
+ {
+ return (StatementNode) nodeFactory.getNode
+ (C_NodeTypes.SET_ROLE_NODE,
+ roleName,
+ null,
+ getContextManager());
+ }
+|
+ dynamicParameterSpecification()
+ {
+ return (StatementNode) nodeFactory.getNode
+ (C_NodeTypes.SET_ROLE_NODE,
+ null,
+ ReuseFactory.getInteger(StatementType.SET_ROLE_DYNAMIC),
+ getContextManager());
+ }
+}
+
+
StatementNode
setSchemaStatement() throws StandardException :
{
@@ -11923,6 +12066,32 @@
}
}
+
+/*
+ * <A NAME="dropRoleStatement">dropRoleStatement</A>
+ */
+StatementNode
+dropRoleStatement() throws StandardException :
+{
+ String roleName;
+}
+{
+ /*
+ * DROP ROLE <rolename>
+ */
+ <ROLE> roleName = identifier(Limits.MAX_IDENTIFIER_LENGTH, true)
+ {
+ checkSqlStandardAccess("DROP ROLE");
+ checkVersion( DataDictionary.DD_VERSION_DERBY_10_4, "ROLES");
+
+ return (StatementNode) nodeFactory.getNode(
+ C_NodeTypes.DROP_ROLE_NODE,
+ roleName,
+ getContextManager());
+ }
+}
+
+
StatementNode
dropSchemaStatement() throws StandardException :
{
@@ -12454,9 +12623,33 @@
StatementNode
grantStatement() throws StandardException :
{
- StatementNode node;
+ StatementNode node;
}
{
+ /* TRIGGER is a non-reserved word, so it is allowed as role
+ * identifier. This gives a parser problem in determining if
+ * a grant statement is a grant role or grant privilege
+ * statement. In a grant privilege statement, all the other
+ * grantable privileges are reserved keywords, except
+ * TRIGGER. So, if we encounter GRANT TRIGGER, we need to look
+ * one or two more tokens ahead to determine what kind of
+ * grant statement we are seeing:
+ *
+ * privilege grant:
+ * grant trigger , <any of rest of privilege keywords>
+ * grant trigger on ..
+ * grant <any of rest of privilege keywords>
+ * role grant:
+ * grant trigger to ..
+ * grant trigger, <NOT any of rest of privilege keywords>
+ * grant <NOT any of rest of privilege keywords>
+ */
+ LOOKAHEAD( { getToken(1).kind == GRANT &&
+ ((getToken(2).kind == TRIGGER &&
+ ((getToken(3).kind == COMMA &&
+ isPrivilegeKeywordExceptTrigger(getToken(4).kind)) ||
+ getToken(3).kind == ON)) ||
+ isPrivilegeKeywordExceptTrigger(getToken(2).kind)) } )
<GRANT>
{
checkVersion( DataDictionary.DD_VERSION_DERBY_10_2, "GRANT");
@@ -12466,6 +12659,24 @@
{
return node;
}
+|
+ LOOKAHEAD( { getToken(1).kind == GRANT &&
+ ((getToken(2).kind == TRIGGER &&
+ ((getToken(3).kind == COMMA &&
+ !isPrivilegeKeywordExceptTrigger(getToken(4).kind)) ||
+ getToken(3).kind == TO)) ||
+ !isPrivilegeKeywordExceptTrigger(getToken(2).kind)) } )
+ <GRANT>
+ {
+ checkSqlStandardAccess("GRANT <role>");
+ checkVersion( DataDictionary.DD_VERSION_DERBY_10_4, "ROLES");
+ }
+ ( node = roleGrantStatement() )
+ {
+ checkVersion( DataDictionary.DD_VERSION_DERBY_10_2, "GRANT");
+ checkSqlStandardAccess( "GRANT");
+ return node;
+ }
}
/*
@@ -12684,6 +12895,67 @@
}
}
+
+/*
+ * <A NAME="roleGrantStatement">roleGrantStatement</A>
+ */
+StatementNode
+roleGrantStatement() throws StandardException :
+{
+ List rolesGranted;
+ List grantees;
+}
+{
+ /*
+ * GRANT <rolename> {, <rolename>}* TO <authentication identifier>
+ * {, <authentication identifier>}*
+ *
+ * not implemented: WITH ADMIN OPTION, GRANTED BY clauses
+ */
+ rolesGranted = roleList()
+ <TO>
+ grantees = granteeList()
+ {
+ return (StatementNode) nodeFactory.getNode
+ (C_NodeTypes.GRANT_ROLE_NODE,
+ rolesGranted,
+ grantees,
+ getContextManager());
+ }
+}
+
+
+/*
+ * <A NAME="roleList">roleList</A>
+ */
+List roleList() throws StandardException :
+{
+ ArrayList list = new ArrayList();
+}
+{
+ roleElement(list) ( <COMMA> roleElement(list) ) *
+ {
+ return list;
+ }
+}
+
+
+/*
+ * <A NAME="roleElement">roleElement</A>
+ */
+void
+roleElement( List list) throws StandardException :
+{
+ String str;
+}
+{
+ str = identifier(Limits.MAX_IDENTIFIER_LENGTH, true)
+ {
+ list.add(str);
+ }
+}
+
+
/*
* <A NAME="revokeStatement">revokeStatement</A>
*/
@@ -12693,15 +12965,48 @@
StatementNode node;
}
{
- <REVOKE>
- {
- checkVersion( DataDictionary.DD_VERSION_DERBY_10_2, "REVOKE");
- checkSqlStandardAccess( "REVOKE");
- }
- ( node = tableRevokeStatement() | node = routineRevokeStatement() )
- {
- return node;
- }
+ /* See look-ahead explanation in grantStatement.
+ *
+ * privilege revoke:
+ * revoke trigger , <any of rest of privilege keywords>
+ * revoke trigger on ..
+ * revoke <any of rest of privilege keywords>
+ * role revoke:
+ * revoke trigger from ..
+ * revoke trigger, <NOT any of rest of privilege keywords>
+ * revoke <NOT any of rest of privilege keywords>
+ */
+ LOOKAHEAD( { getToken(1).kind == REVOKE &&
+ ((getToken(2).kind == TRIGGER &&
+ ((getToken(3).kind == COMMA &&
+ isPrivilegeKeywordExceptTrigger(getToken(4).kind)) ||
+ getToken(3).kind == ON)) ||
+ isPrivilegeKeywordExceptTrigger(getToken(2).kind)) } )
+ <REVOKE>
+ {
+ checkVersion( DataDictionary.DD_VERSION_DERBY_10_2, "REVOKE");
+ checkSqlStandardAccess( "REVOKE");
+ }
+ ( node = tableRevokeStatement() | node = routineRevokeStatement() )
+ {
+ return node;
+ }
+|
+ LOOKAHEAD( { getToken(1).kind == REVOKE &&
+ ((getToken(2).kind == TRIGGER &&
+ ((getToken(3).kind == COMMA &&
+ !isPrivilegeKeywordExceptTrigger(getToken(4).kind)) ||
+ getToken(3).kind == FROM)) ||
+ !isPrivilegeKeywordExceptTrigger(getToken(2).kind)) } )
+ <REVOKE>
+ {
+ checkSqlStandardAccess("REVOKE <role>");
+ checkVersion( DataDictionary.DD_VERSION_DERBY_10_4, "ROLES");
+ }
+ ( node = roleRevokeStatement() )
+ {
+ return node;
+ }
}
/*
@@ -12747,6 +13052,29 @@
}
}// end of routineRevokeStatement
+
+/*
+ * <A NAME="roleRevokeStatement">roleRevokeStatement</A>
+ */
+StatementNode
+roleRevokeStatement() throws StandardException :
+{
+ List rolesRevokeed;
+ List grantees;
+}
+{
+ rolesRevokeed = roleList()
+ <FROM>
+ grantees = granteeList()
+ {
+ return (StatementNode) nodeFactory.getNode
+ (C_NodeTypes.REVOKE_ROLE_NODE,
+ rolesRevokeed,
+ grantees,
+ getContextManager());
+ }
+}
+
/*
* <A NAME="identifier">identifier</A>
*/
@@ -12970,6 +13298,7 @@
| tok = <NVARCHAR>
| tok = <NEXT>
| tok = <NO>
+| tok = <NONE>
| tok = <NOT>
| tok = <NULL>
| tok = <NULLIF>
@@ -13049,6 +13378,7 @@
/* Additional JSQL reserved keywords -- non-SQL92 reserved Keywords */
| tok = <BOOLEAN>
| tok = <CALL>
+| tok = <CURRENT_ROLE>
| tok = <EXPLAIN>
| tok = <LONGINT>
| tok = <LTRIM>
@@ -13184,6 +13514,7 @@
| tok = <RETAIN>
| tok = <RETURNING>
| tok = <RETURNS>
+ | tok = <ROLE>
| tok = <ROW>
// | tok = <ROW_COUNT>
| tok = <RR>
Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/RolesTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/RolesTest.java?rev=584738&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/RolesTest.java (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/RolesTest.java Mon Oct 15 04:24:15 2007
@@ -0,0 +1,445 @@
+/*
+
+ Derby - Class org.apache.derbyTesting.functionTests.tests.jdbcapi.RolesTest
+
+ 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.derbyTesting.functionTests.tests.lang;
+
+import java.sql.SQLException;
+import java.sql.Connection;
+import java.sql.Statement;
+import java.sql.PreparedStatement;
+import javax.sql.DataSource;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.apache.derbyTesting.junit.BaseJDBCTestCase;
+import org.apache.derbyTesting.junit.DatabasePropertyTestSetup;
+import org.apache.derbyTesting.junit.JDBC;
+import org.apache.derbyTesting.junit.JDBCDataSource;
+import org.apache.derbyTesting.junit.TestConfiguration;
+
+/**
+ * This JUnit tests the SQL roles feature. This feature relies on
+ * sqlAuthorization being set. Upgrade tests are not handled here.
+ *
+ * The tests are run in the cross product:
+ *
+ * {client/server, embedded} x
+ * {no sqlAuthorization/sqlAuthorization} x
+ * {data base owner, other user }
+ *
+ */
+public class RolesTest extends BaseJDBCTestCase
+{
+ /* internal state */
+ private final int _authLevel;
+ private final String _user;
+ private final String _userPassword;
+ private Connection _conn;
+ private Statement _stm;
+
+ /* test execution security context: one of two below */
+ private final static int NO_SQLAUTHORIZATION=0;
+ private final static int SQLAUTHORIZATION=1;
+
+ private final static String pwSuffix = "pwSuffix";
+
+ /* SQL states */
+ private final static String sqlAuthorizationRequired = "42Z60";
+ private final static String syntaxError = "42X01";
+ // temporary until feature fully implemented:
+ private final static String notImplemented = "0A000";
+
+ /**
+ * Users used by all suites when when authLevel == SQLAUTHORIZATION.
+ * The TestConfiguration.sqlAuthorizationDecorator decorator presumes
+ * TEST_DBO as dbo, so add it to set of valid users. It uses a fresh db
+ * 'dbsqlauth', not 'wombat'.
+ */
+ private final static String[] users = {"TEST_DBO", "DonaldDuck"};
+
+ private boolean isDbo() {
+ return users[0].equals(this._user);
+ }
+
+ /**
+ * Create a new instance of RolesTest.
+ *
+ * @param name Fixture name
+ * @param authLevel authentication level with which test is run
+ * @param user Database user
+ * @param userPassword Database user's password
+ */
+
+ public RolesTest(String name, int authLevel,
+ String user, String userPassword)
+ {
+ super(name);
+ this._authLevel = authLevel;
+ this._user = user;
+ this._userPassword = userPassword;
+ }
+
+
+ /**
+ * Construct top level suite in this JUnit test
+ *
+ * @return A suite containing embedded and client suites.
+ * Client/server suite commented out to speed up this test as
+ * it does not add much value given the nature of the changes
+ * (SQL language only).
+ */
+ public static Test suite()
+ {
+ TestSuite suite = new TestSuite("RolesTest");
+
+ /* Negative syntax tests */
+ suite.addTest(negativeSyntaxSuite("suite: negative syntax, embedded"));
+
+ // suite.addTest(
+ // TestConfiguration.clientServerDecorator(
+ // negativeSyntaxSuite("suite: negative syntax, client")));
+
+ /* Positive tests */
+ suite.addTest(
+ positiveSuite("suite: positive, embedded"));
+
+ // suite.addTest(
+ // TestConfiguration.clientServerDecorator(
+ // positiveSuite("suite: positive, client")));
+
+ return suite;
+ }
+
+ /**
+ *
+ * Construct suite of tests for negative syntax
+ *
+ * @param framework Derby framework indication
+ * @return A suite containing the test cases for negative syntax
+ * incarnated for the two security levels no sqlAuthorization, and
+ * sqlAuthorization, The latter has an instance for dbo, and one
+ * for an ordinary user, so there are in all three incarnations of
+ * tests.
+ */
+ private static Test negativeSyntaxSuite(String framework)
+ {
+ Test tests[] = new Test[SQLAUTHORIZATION+1]; // one per authLevel
+
+ /* Tests running without sql authorization set.
+ */
+ TestSuite noauthSuite = new TestSuite(
+ "suite: security level=noSqlAuthorization");
+ noauthSuite.addTest(new RolesTest("testNegativeSyntax",
+ NO_SQLAUTHORIZATION,
+ null,
+ null));
+ tests[NO_SQLAUTHORIZATION] = noauthSuite;
+
+ /* Tests running with sql authorization set.
+ * First decorate with users, then with authentication +
+ * sqlAuthorization.
+ */
+ tests[SQLAUTHORIZATION] = wrapTest("testNegativeSyntax");
+
+
+ TestSuite suite = new TestSuite("roles:"+framework);
+ suite.addTest(tests[NO_SQLAUTHORIZATION]);
+ suite.addTest(tests[SQLAUTHORIZATION]);
+
+ return suite;
+ }
+
+
+
+ /**
+ * Wraps the negative syntax fixture in decorators to run with
+ * data base owner and one other valid user in sqlAuthorization
+ * mode.
+ */
+
+ /**
+ * Test negative syntax for roles.
+ *
+ * @throws SQLException
+ */
+ public void testNegativeSyntax() throws SQLException
+ {
+ println("testNegativeSyntax: auth=" + this._authLevel +
+ " user="+getTestConfiguration().getUserName());
+
+ _conn = getConnection();
+ _stm = _conn.createStatement();
+
+ doStmt("create role none", // none is reserved word
+ syntaxError, syntaxError, syntaxError);
+ doStmt("create role current_role", // current_role is reserved word
+ syntaxError, syntaxError, syntaxError);
+ }
+
+ /**
+ *
+ * Construct suite of positive tests
+ *
+ * @param framework Derby framework indication
+ *
+ * @return A suite containing the positive test cases incarnated only
+ * for security level sqlAuthorization.
+ *
+ * It has one instance for dbo, and one for an ordinary user, so there
+ * are in all three incarnations of tests.
+ */
+ private static Test positiveSuite(String framework)
+ {
+ Test tests[] = new Test[SQLAUTHORIZATION+1]; // one per authLevel
+ /* Tests running without sql authorization set.
+ */
+ TestSuite noauthSuite = new TestSuite(
+ "suite: security level=noSqlAuthorization");
+ noauthSuite.addTest(new RolesTest("testPositive",
+ NO_SQLAUTHORIZATION,
+ null,
+ null));
+ tests[NO_SQLAUTHORIZATION] = noauthSuite;
+ /* Tests running with sql authorization set.
+ * First decorate with users, then with authentication +
+ * sqlAuthorization.
+ */
+ TestSuite suite = new TestSuite("roles:"+framework);
+ tests[SQLAUTHORIZATION] = wrapTest("testPositive");
+
+ suite.addTest(tests[NO_SQLAUTHORIZATION]);
+ suite.addTest(tests[SQLAUTHORIZATION]);
+
+ return suite;
+ }
+
+ /**
+ * Wraps in decorators to run with data base owner and one other
+ * valid user in sqlAuthorization mode.
+ *
+ * @param testName test to wrap
+ */
+ private static Test wrapTest(String testName)
+ {
+ // add decorator for different users authenticated
+ TestSuite usersSuite =
+ new TestSuite("suite: security level=sqlAuthorization");
+
+ // First decorate with users, then with authorization
+ // decorator
+ for (int userNo = 0; userNo < users.length; userNo++) {
+ usersSuite.addTest
+ (TestConfiguration.changeUserDecorator
+ (new RolesTest(testName,
+ SQLAUTHORIZATION,
+ users[userNo],
+ users[userNo].concat(pwSuffix)),
+ users[userNo],
+ users[userNo].concat(pwSuffix)));
+ }
+
+ return TestConfiguration.sqlAuthorizationDecorator(
+ DatabasePropertyTestSetup.builtinAuthentication(
+ usersSuite, users, pwSuffix));
+ }
+
+ /**
+ * Positive tests for roles (well, positive for dbo at least!)
+ *
+ * @throws SQLException
+ */
+ public void testPositive() throws SQLException
+ {
+ println("testPositive: auth=" + this._authLevel +
+ " user="+getTestConfiguration().getUserName());
+
+ _conn = getConnection();
+ _stm = _conn.createStatement();
+
+ // create
+ doStmt("create role foo",
+ sqlAuthorizationRequired, notImplemented, notImplemented);
+ doStmt("create role bar",
+ sqlAuthorizationRequired, notImplemented, notImplemented);
+ doStmt("create role role", // role is not reserved word
+ sqlAuthorizationRequired, notImplemented, notImplemented);
+ doStmt("create role trigger",
+ sqlAuthorizationRequired, notImplemented, notImplemented);
+ doStmt("create role \"NONE\"", // quoted role id should work
+ sqlAuthorizationRequired, notImplemented, notImplemented);
+
+ // grant
+ doStmt("grant foo to authid", // authid: user or role
+ sqlAuthorizationRequired, notImplemented, notImplemented);
+ doStmt("grant foo, role, bar to authid1, authid2, authid3",
+ sqlAuthorizationRequired, notImplemented, notImplemented);
+
+ // grant: parser look-ahead tests to discern grant role from
+ // grant privilege
+ doStmt("grant trigger to authid",
+ sqlAuthorizationRequired, notImplemented, notImplemented);
+ doStmt("grant trigger, foo to authid",
+ sqlAuthorizationRequired, notImplemented, notImplemented);
+ doStmt("grant trigger, foo to public",
+ sqlAuthorizationRequired, notImplemented, notImplemented);
+
+
+ // set
+ doStmt("set role foo",
+ sqlAuthorizationRequired, notImplemented, notImplemented);
+ doStmt("set role none",
+ sqlAuthorizationRequired, notImplemented, notImplemented);
+ doDynamicSetRole(_conn);
+
+ // revoke
+
+ doStmt("revoke foo from authid", // authid: user or role
+ sqlAuthorizationRequired, notImplemented, notImplemented);
+ doStmt("revoke foo, role, bar from authid1, authid2, authid3",
+ sqlAuthorizationRequired, notImplemented, notImplemented);
+
+ // revoke: parser look-ahead tests to discern revoke role from
+ // revoke privilege
+ doStmt("revoke trigger from authid",
+ sqlAuthorizationRequired, notImplemented, notImplemented);
+ doStmt("revoke trigger, foo from authid",
+ sqlAuthorizationRequired, notImplemented, notImplemented);
+ doStmt("revoke trigger, foo from public",
+ sqlAuthorizationRequired, notImplemented, notImplemented);
+
+ // drop
+ doStmt("drop role foo",
+ sqlAuthorizationRequired, notImplemented, notImplemented);
+ doStmt("drop role role",
+ sqlAuthorizationRequired, notImplemented, notImplemented);
+ doStmt("drop role trigger",
+ sqlAuthorizationRequired, notImplemented, notImplemented);
+ doStmt("drop role \"NONE\"",
+ sqlAuthorizationRequired, notImplemented, notImplemented);
+
+ // current_role
+ doStmt("values current_role",
+ sqlAuthorizationRequired, notImplemented, notImplemented);
+
+ // column default current_role
+ doStmt("create table foo(str varchar(128) default current_role)",
+ sqlAuthorizationRequired, notImplemented, notImplemented);
+ }
+
+ // Minion to analyze outcome. If state string is empty, we expect success
+ // for that combination of authentication level and user (dbo or not).
+ private void doStmt(String stmt,
+ String noAuthState,
+ String authDboState,
+ String authNotDboState) {
+ try {
+ _stm.execute(stmt);
+ if (_authLevel == NO_SQLAUTHORIZATION) {
+ if (noAuthState != null) {
+ fail("exception " + noAuthState + " expected: (" + stmt);
+ }
+ } else { // SQLAUTHORIZATION
+ if (isDbo()) {
+ if (authDboState != null) {
+ fail("exception " + noAuthState + " expected: (" +
+ stmt);
+ }
+ } else {
+ if (authNotDboState != null) {
+ fail("exception " + noAuthState + " expected: (" +
+ stmt);
+ }
+ }
+ }
+ } catch (SQLException e) {
+ if (_authLevel == NO_SQLAUTHORIZATION) {
+ if (noAuthState == null) {
+ fail("stmt " + stmt + " failed with exception " +
+ e.getSQLState());
+ } else {
+ assertSQLState("Stmt " + stmt, noAuthState, e);
+ }
+
+ } else { // SQLAUTHORIZATION
+ if (isDbo()) {
+ if (authDboState == null) {
+ fail("stmt " + stmt + " failed with exception " +
+ e.getSQLState());
+ } else {
+ assertSQLState("Stmt " + stmt, authDboState, e);
+ }
+ } else {
+ if (authNotDboState == null) {
+ fail("stmt " + stmt + " failed with exception " +
+ e.getSQLState());
+ } else {
+ assertSQLState("Stmt " + stmt, authNotDboState, e);
+ }
+ }
+ }
+ }
+ }
+
+
+ private void doDynamicSetRole(Connection conn) {
+ PreparedStatement pstmt = null;
+
+ try {
+ pstmt = conn.prepareStatement("set role ?");
+
+ if (_authLevel == NO_SQLAUTHORIZATION) {
+ fail("set role ? should have failed; no sqlAuthorization");
+ }
+ } catch (SQLException e) {
+ if (_authLevel == NO_SQLAUTHORIZATION) {
+ assertSQLState(sqlAuthorizationRequired, e);
+ return;
+ } else {
+ // fail("prepare of set role ? failed:" + e);
+ assertSQLState(notImplemented, e);
+ return;
+ }
+ }
+
+ try {
+ pstmt.setString(1, "foo");
+ int rowcnt = pstmt.executeUpdate();
+ assertEquals(rowcnt, 0, "rowcount from set role ? not 0");
+ } catch (SQLException e) {
+ assertSQLState(notImplemented, e);
+ }
+
+
+ try {
+ pstmt.setString(1, "\"NONE\"");
+ int rowcnt = pstmt.executeUpdate();
+ assertEquals(rowcnt, 0, "rowcount from set role ? not 0");
+ } catch (SQLException e) {
+ assertSQLState(notImplemented, e);
+ }
+ }
+
+
+ private void assertEquals(int a, int b, String txt) {
+ if (a!=b) {
+ fail(txt);
+ }
+ }
+}
Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/RolesTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java?rev=584738&r1=584737&r2=584738&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java Mon Oct 15 04:24:15 2007
@@ -69,6 +69,7 @@
suite.addTest(LangScripts.suite());
suite.addTest(MathTrigFunctionsTest.suite());
suite.addTest(PrepareExecuteDDL.suite());
+ suite.addTest(RolesTest.suite());
suite.addTest(RoutineSecurityTest.suite());
suite.addTest(RoutineTest.suite());
suite.addTest(SQLAuthorizationPropTest.suite());