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;