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 rh...@apache.org on 2014/04/03 03:18:50 UTC
svn commit: r1584242 - in /db/derby/code/trunk/java:
optional/org/apache/derby/optional/lucene/
testing/org/apache/derbyTesting/functionTests/tests/lang/
Author: rhillegas
Date: Thu Apr 3 01:18:49 2014
New Revision: 1584242
URL: http://svn.apache.org/r1584242
Log:
DERBY-590: Enforce coarse-grained authorization checks in the Lucene plugin; commit derby-590-14-aa-coarseGrainedAuthorization.diff.
Added:
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneCoarseAuthorizationTest.java (with props)
Modified:
db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/LuceneSupport.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneSuite.java
Modified: db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/LuceneSupport.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/LuceneSupport.java?rev=1584242&r1=1584241&r2=1584242&view=diff
==============================================================================
--- db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/LuceneSupport.java (original)
+++ db/derby/code/trunk/java/optional/org/apache/derby/optional/lucene/LuceneSupport.java Thu Apr 3 01:18:49 2014
@@ -47,6 +47,7 @@ import java.util.Arrays;
import java.util.ArrayList;
import java.util.Properties;
+import org.apache.derby.iapi.sql.conn.ConnectionUtil;
import org.apache.derby.iapi.sql.dictionary.OptionalTool;
import org.apache.derby.iapi.error.StandardException;
import org.apache.derby.iapi.util.IdUtil;
@@ -135,6 +136,8 @@ public class LuceneSupport implements Op
*/
public void loadTool(String... configurationParameters) throws SQLException
{
+ forbidReadOnlyConnections();
+
Connection conn = getDefaultConnection();
mustBeDBO( conn );
@@ -221,6 +224,8 @@ public class LuceneSupport implements Op
public void unloadTool(String... configurationParameters)
throws SQLException
{
+ forbidReadOnlyConnections();
+
Connection conn = getDefaultConnection();
mustBeDBO( conn );
@@ -337,6 +342,8 @@ public class LuceneSupport implements Op
throws SQLException, IOException, PrivilegedActionException,
ClassNotFoundException, IllegalAccessException, InvocationTargetException, NoSuchMethodException
{
+ forbidReadOnlyConnections();
+
Connection conn = getDefaultConnection();
// only the dbo or the schema owner can perform this function
@@ -378,6 +385,8 @@ public class LuceneSupport implements Op
throws SQLException, IOException, PrivilegedActionException,
ClassNotFoundException, IllegalAccessException, InvocationTargetException, NoSuchMethodException
{
+ forbidReadOnlyConnections();
+
Connection conn = getDefaultConnection();
DatabaseMetaData dbmd = conn.getMetaData();
@@ -551,6 +560,8 @@ public class LuceneSupport implements Op
public static void dropIndex( String schema, String table, String textcol )
throws SQLException, IOException, PrivilegedActionException
{
+ forbidReadOnlyConnections();
+
getDefaultConnection().prepareStatement
(
"drop function " + makeTableFunctionName( schema, table, textcol )
@@ -1118,6 +1129,18 @@ public class LuceneSupport implements Op
//
/////////////////////////////////////////////////////////////////////
+ /**
+ * Raise an error if the connection is readonly.
+ */
+ private static void forbidReadOnlyConnections()
+ throws SQLException
+ {
+ if ( ConnectionUtil.getCurrentLCC().getAuthorizer().isReadOnlyConnection() )
+ {
+ throw newSQLException( SQLState.AUTH_WRITE_WITH_READ_ONLY_CONNECTION );
+ }
+ }
+
/**
* Get a connection to the database
*
Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneCoarseAuthorizationTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneCoarseAuthorizationTest.java?rev=1584242&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneCoarseAuthorizationTest.java (added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneCoarseAuthorizationTest.java Thu Apr 3 01:18:49 2014
@@ -0,0 +1,368 @@
+/*
+
+ Derby - Class org.apache.derbyTesting.functionTests.tests.lang.LuceneCoarseAuthorizationTest
+
+ 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.io.File;
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Connection;
+import java.sql.Date;
+import java.sql.Statement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Properties;
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.apache.derby.iapi.sql.conn.ConnectionUtil;
+import org.apache.derbyTesting.junit.BaseJDBCTestCase;
+import org.apache.derbyTesting.junit.JDBC;
+import org.apache.derbyTesting.junit.DatabasePropertyTestSetup;
+import org.apache.derbyTesting.junit.LocaleTestSetup;
+import org.apache.derbyTesting.junit.SecurityManagerSetup;
+import org.apache.derbyTesting.junit.TestConfiguration;
+import org.apache.derbyTesting.junit.CleanDatabaseTestSetup;
+
+/**
+ * <p>
+ * Test permissions on objects created by the optional Lucene support tool.
+ * </p>
+ */
+public class LuceneCoarseAuthorizationTest extends GeneratedColumnsHelper
+{
+ ///////////////////////////////////////////////////////////////////////////////////
+ //
+ // CONSTANTS
+ //
+ ///////////////////////////////////////////////////////////////////////////////////
+
+ private static final String RUTH = "RUTH";
+ private static final String READ_ONLY_USER = "READONLYUSER";
+ private static final String READ_WRITE_USER = "READWRITEUSER";
+ private static final String[] LEGAL_USERS = { RUTH, READ_ONLY_USER, READ_WRITE_USER };
+
+ private static final String LOAD_TOOL = "call syscs_util.syscs_register_tool( 'luceneSupport', true )";
+ private static final String UNLOAD_TOOL = "call syscs_util.syscs_register_tool( 'luceneSupport', false )";
+ private static final String INDEX_POEMS = "call LuceneSupport.createIndex( 'ruth', 'poems', 'poemText', null )";
+ private static final String UPDATE_POEMS_INDEX =
+ "call LuceneSupport.updateIndex( 'ruth', 'poems', 'poemText', 'org.apache.derby.optional.api.LuceneUtils.standardAnalyzer' )";
+ private static final String DROP_POEMS_INDEX = "call LuceneSupport.dropIndex( 'ruth', 'poems', 'poemText' )";
+
+ private static final String ILLEGAL_FOR_READONLY = "25502";
+
+ ///////////////////////////////////////////////////////////////////////////////////
+ //
+ // STATE
+ //
+ ///////////////////////////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////////////////////////
+ //
+ // CONSTRUCTOR
+ //
+ ///////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Create a new instance.
+ */
+
+ public LuceneCoarseAuthorizationTest(String name)
+ {
+ super(name);
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////
+ //
+ // JUnit BEHAVIOR
+ //
+ ///////////////////////////////////////////////////////////////////////////////////
+
+
+ /**
+ * Construct top level suite in this JUnit test
+ */
+ public static Test suite()
+ {
+ TestSuite suite = (TestSuite) TestConfiguration.embeddedSuite(LuceneCoarseAuthorizationTest.class);
+
+ Test unsecureTest = SecurityManagerSetup.noSecurityManager( suite );
+ Test authenticatedTest = DatabasePropertyTestSetup.builtinAuthentication
+ ( unsecureTest, LEGAL_USERS, "LuceneCoarsePermissions" );
+
+ Test coarseTest = new DatabasePropertyTestSetup( authenticatedTest, makeProperties() );
+
+ return coarseTest;
+ }
+ private static Properties makeProperties()
+ {
+ Properties props = new Properties();
+
+ props.setProperty( "derby.database.fullAccessUsers", RUTH + "," + READ_WRITE_USER );
+ props.setProperty( "derby.database.readOnlyAccessUsers", READ_ONLY_USER );
+
+ return props;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////////////
+ //
+ // TESTS
+ //
+ ///////////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * <p>
+ * Test that read-only users can't (un)load the tool or create/update indexes. But
+ * they can view data.
+ * </p>
+ */
+ public void test_001_basic()
+ throws Exception
+ {
+ Connection ruthConnection = openUserConnection( RUTH );
+ Connection readOnlyConnection = openUserConnection( READ_ONLY_USER );
+ Connection readWriteConnection = openUserConnection( READ_WRITE_USER );
+
+ createSchema( ruthConnection );
+
+ expectExecutionError
+ (
+ readOnlyConnection,
+ ILLEGAL_FOR_READONLY,
+ LOAD_TOOL
+ );
+ goodStatement( readWriteConnection, LOAD_TOOL );
+
+ expectExecutionError
+ (
+ readOnlyConnection,
+ ILLEGAL_FOR_READONLY,
+ INDEX_POEMS
+ );
+ goodStatement( readWriteConnection, INDEX_POEMS );
+
+ String readPoemsIndex =
+ "select p.originalAuthor, i.rank\n" +
+ "from ruth.poems p, table ( ruth.poems__poemText( 'star', 0 ) ) i\n" +
+ "where p.poemID = i.poemID and p.versionStamp = i.versionStamp\n" +
+ "order by i.rank desc\n";
+ String[][] defaultPoemResults =
+ new String[][]
+ {
+ { "Walt Whitman", "0.26756266" },
+ { "Lord Byron", "0.22933942" },
+ { "John Milton", "0.22933942" },
+ };
+
+ assertResults
+ (
+ readOnlyConnection,
+ readPoemsIndex,
+ defaultPoemResults,
+ false
+ );
+ assertResults
+ (
+ readWriteConnection,
+ readPoemsIndex,
+ defaultPoemResults,
+ false
+ );
+
+ String listIndexes =
+ "select schemaName, tableName, columnName, analyzerMaker from table( LuceneSupport.listIndexes() ) l";
+ String[][] defaultIndexList =
+ new String[][]
+ {
+ { "RUTH", "POEMS", "POEMTEXT", "org.apache.derby.optional.api.LuceneUtils.defaultAnalyzer" },
+ };
+
+ assertResults
+ (
+ readOnlyConnection,
+ listIndexes,
+ defaultIndexList,
+ false
+ );
+ assertResults
+ (
+ readWriteConnection,
+ listIndexes,
+ defaultIndexList,
+ false
+ );
+
+ expectExecutionError
+ (
+ readOnlyConnection,
+ ILLEGAL_FOR_READONLY,
+ UPDATE_POEMS_INDEX
+ );
+ goodStatement( readWriteConnection, UPDATE_POEMS_INDEX );
+
+ String[][] standardPoemResults =
+ new String[][]
+ {
+ { "Walt Whitman", "0.3304931" },
+ { "John Milton", "0.2832798" },
+ };
+
+ assertResults
+ (
+ readOnlyConnection,
+ readPoemsIndex,
+ standardPoemResults,
+ false
+ );
+ assertResults
+ (
+ readWriteConnection,
+ readPoemsIndex,
+ standardPoemResults,
+ false
+ );
+
+ String[][] standardIndexList =
+ new String[][]
+ {
+ { "RUTH", "POEMS", "POEMTEXT", "org.apache.derby.optional.api.LuceneUtils.standardAnalyzer" },
+ };
+
+ assertResults
+ (
+ readOnlyConnection,
+ listIndexes,
+ standardIndexList,
+ false
+ );
+ assertResults
+ (
+ readWriteConnection,
+ listIndexes,
+ standardIndexList,
+ false
+ );
+
+ expectExecutionError
+ (
+ readOnlyConnection,
+ ILLEGAL_FOR_READONLY,
+ DROP_POEMS_INDEX
+ );
+ goodStatement( readWriteConnection, DROP_POEMS_INDEX );
+
+ expectExecutionError
+ (
+ readOnlyConnection,
+ ILLEGAL_FOR_READONLY,
+ UNLOAD_TOOL
+ );
+ goodStatement( readWriteConnection, UNLOAD_TOOL );
+
+ dropSchema( ruthConnection );
+ }
+
+
+ ///////////////////////////////////////////////////////////////////////////////////
+ //
+ // MINIONS
+ //
+ ///////////////////////////////////////////////////////////////////////////////////
+
+ private void createSchema( Connection conn ) throws Exception
+ {
+ createPoemsTable( conn );
+ }
+ private void dropSchema( Connection conn ) throws Exception
+ {
+ goodStatement( conn, "drop table poems" );
+ }
+ private void createPoemsTable( Connection conn )
+ throws Exception
+ {
+ goodStatement
+ (
+ conn,
+ "create table poems\n" +
+ "(\n" +
+ " poemID int,\n" +
+ " versionStamp int not null,\n" +
+ " originalAuthor varchar( 50 ),\n" +
+ " lastEditor varchar( 50 ),\n" +
+ " poemText clob,\n" +
+ " constraint poemsKey primary key( poemID, versionStamp )\n" +
+ ")\n"
+ );
+
+ PreparedStatement ps = conn.prepareStatement( "insert into poems values ( ?, ?, ?, ?, ? )" );
+
+ int poemID = 1;
+ int versionStamp = 1;
+
+ ps.setInt( 1, poemID++ );
+ ps.setInt( 2, versionStamp++ );
+ ps.setString( 3, "Geoffrey Chaucer" );
+ ps.setString( 4, "Geoffrey Chaucer" );
+ ps.setString( 5, "Whan that Aprill, with his shoures soote The droghte of March hath perced to the roote And bathed every veyne in swich licour, Of which vertu engendred is the flour;" );
+ ps.executeUpdate();
+
+ ps.setInt( 1, poemID++ );
+ ps.setInt( 2, versionStamp++ );
+ ps.setString( 3, "Andrew Marvell" );
+ ps.setString( 4, "Andrew Marvell" );
+ ps.setString( 5, "Had we but world enough, and time, This coyness, lady, were no crime." );
+ ps.executeUpdate();
+
+ ps.setInt( 1, poemID++ );
+ ps.setInt( 2, versionStamp++ );
+ ps.setString( 3, "John Milton" );
+ ps.setString( 4, "John Milton" );
+ ps.setString( 5, "From morn to noon he fell, from noon to dewy eve, a summers day, and with the setting sun dropped from the ze4ith like a falling star on Lemnos, the Aegean isle" );
+ ps.executeUpdate();
+
+ ps.setInt( 1, poemID++ );
+ ps.setInt( 2, versionStamp++ );
+ ps.setString( 3, "Lord Byron" );
+ ps.setString( 4, "Lord Byron" );
+ ps.setString( 5, "The Assyrian came down like the wolf on the fold, And his cohorts were gleaming in purple and gold; And the sheen of their spears was like stars on the sea, When the blue wave rolls nightly on deep Galilee." );
+ ps.executeUpdate();
+
+ ps.setInt( 1, poemID++ );
+ ps.setInt( 2, versionStamp++ );
+ ps.setString( 3, "Walt Whitman" );
+ ps.setString( 4, "Walt Whitman" );
+ ps.setString( 5, "When lilacs last in the dooryard bloomd, And the great star early droopd in the western sky in the night, I mournd, and yet shall mourn with ever-returning spring." );
+ ps.executeUpdate();
+
+ ps.close();
+ }
+
+
+}
Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneCoarseAuthorizationTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneSuite.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneSuite.java?rev=1584242&r1=1584241&r2=1584242&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneSuite.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/LuceneSuite.java Thu Apr 3 01:18:49 2014
@@ -63,6 +63,7 @@ public class LuceneSuite extends BaseTes
suite.addTest(LuceneSupportTest.suite());
suite.addTest(LuceneSupportPermsTest.suite());
suite.addTest(LuceneCollationTest.suite());
+ suite.addTest(LuceneCoarseAuthorizationTest.suite());
}
return suite;