summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJens Vagelpohl <jens@netz.ooo>2017-07-30 17:34:02 +0200
committerJens Vagelpohl <jens@netz.ooo>2017-07-30 17:34:02 +0200
commitb52d87fa4373fca4d9f160960bbe0b1b9e79cf88 (patch)
tree000583b0db7a76d547e79a146957506a6d8f2e1d
downloadRestrictedZSQLMethods-b52d87fa4373fca4d9f160960bbe0b1b9e79cf88.zip
RestrictedZSQLMethods-b52d87fa4373fca4d9f160960bbe0b1b9e79cf88.tar.gz
- migrate to GitHEADmaster
-rw-r--r--CHANGES.txt6
-rw-r--r--COPYRIGHT.txt9
-rw-r--r--INSTALL.txt13
-rw-r--r--LICENSE.txt54
-rw-r--r--README.txt23
-rw-r--r--RestrictedZSQLMethod.py80
-rw-r--r--VERSION.txt1
-rw-r--r--__init__.py28
-rw-r--r--tests/__init__.py1
-rw-r--r--tests/test_RestrictedZSQLMethods.py119
-rw-r--r--www/add.dtml105
-rw-r--r--www/edit.dtml108
-rw-r--r--www/restrictedsqlmethod.gifbin0 -> 914 bytes
13 files changed, 547 insertions, 0 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
new file mode 100644
index 0000000..de02424
--- /dev/null
+++ b/CHANGES.txt
@@ -0,0 +1,6 @@
+RestrictedZSQLMethods version and change information
+
+ 0.9
+
+ - First release
+
diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt
new file mode 100644
index 0000000..9b5edb5
--- /dev/null
+++ b/COPYRIGHT.txt
@@ -0,0 +1,9 @@
+Copyright (c) 2005 Jens Vagelpohl.
+All Rights Reserved.
+
+This software is subject to the provisions of the Zope Public License,
+Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+FOR A PARTICULAR PURPOSE.
diff --git a/INSTALL.txt b/INSTALL.txt
new file mode 100644
index 0000000..ea934c8
--- /dev/null
+++ b/INSTALL.txt
@@ -0,0 +1,13 @@
+Installing the RestrictedZSQLMethods Product
+
+ First, you will need to unzip and untar the compressed surce
+ file into a place where Zope can find it, namely the
+ "Products" directory.
+
+ $ cp RestrictedZSQLMethods-xyz.tgz <zope_root>/lib/python/Products
+ $ cd <zope_root>/lib/python/Products
+ $ tar zxvf RestrictedZSQLMethods-xyz.tgz
+ <watch files being decompressed>
+
+ Do not forget to restart Zope afterwards. See README.txt for any other
+ dependencies and requirements.
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..89be00b
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,54 @@
+Zope Public License (ZPL) Version 2.1
+
+A copyright notice accompanies this license document that
+identifies the copyright holders.
+
+This license has been certified as open source. It has also
+been designated as GPL compatible by the Free Software
+Foundation (FSF).
+
+Redistribution and use in source and binary forms, with or
+without modification, are permitted provided that the
+following conditions are met:
+
+1. Redistributions in source code must retain the
+ accompanying copyright notice, this list of conditions,
+ and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the accompanying
+ copyright notice, this list of conditions, and the
+ following disclaimer in the documentation and/or other
+ materials provided with the distribution.
+
+3. Names of the copyright holders must not be used to
+ endorse or promote products derived from this software
+ without prior written permission from the copyright
+ holders.
+
+4. The right to distribute this software or to use it for
+ any purpose does not give you the right to use
+ Servicemarks (sm) or Trademarks (tm) of the copyright
+ holders. Use of them is covered by separate agreement
+ with the copyright holders.
+
+5. If any files are modified, you must cause the modified
+ files to carry prominent notices stating that you changed
+ the files and the date of any change.
+
+Disclaimer
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS''
+ AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
+ NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ NO EVENT SHALL THE COPYRIGHT HOLDERS BE
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ DAMAGE.
+
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..45c83e5
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,23 @@
+RestrictedZSQLMethods
+
+ The RestrictedZSQLMethods product provides a specialized ZSQL
+ Method object where the administrator can restrict the database
+ connection objects available for choice in the ZMI selection
+ widget on the ZSQL Method configuration view.
+
+
+ **Usage**
+
+ The restriction works by defining a property on an object in the
+ ZSQL Method's acquisition path which holds a sequence of allowed
+ connection IDs. This property must be of type "lines" if defined
+ through the ZMI Properties view, otherwise it can be either a list
+ or tuple. The property must be named 'allowedAdapters'.
+
+ If no such property can be found or if it contains an empty
+ sequence then all available database adapters are shown, just like
+ on a standard ZSQL Method.
+
+ The property is not looked up on the ZSQL Method itself to prevent
+ malicious usage, only on the ZSQL Method object's container and
+ up the acquisition path from there.
diff --git a/RestrictedZSQLMethod.py b/RestrictedZSQLMethod.py
new file mode 100644
index 0000000..9fe591a
--- /dev/null
+++ b/RestrictedZSQLMethod.py
@@ -0,0 +1,80 @@
+#####################################################################
+#
+# RestrictedZSQLMethods ZSQLMethods with limited connections
+#
+# This software is governed by a license. See
+# LICENSE.txt for the terms of this license.
+#
+#####################################################################
+__version__ = "$Revision: 1199 $"[11:-2]
+
+# General python imports
+
+# Zope imports
+from AccessControl import ClassSecurityInfo
+from AccessControl.Permissions import use_database_methods
+from Acquisition import aq_inner
+from Acquisition import aq_parent
+from Globals import DTMLFile
+from Globals import InitializeClass
+from Products.PageTemplates.PageTemplateFile import PageTemplateFile
+from Products.ZSQLMethods.SQL import SQL
+from Products.ZSQLMethods.SQL import SQLConnectionIDs as ZSQLConnectionIDs
+
+def restrictedSQLConnectionIDs(self):
+ """ Return the restricted sequence of allowed database adapters
+
+ Returns a list of (ID, title) strings for the respective database
+ adapters.
+ It will look up a property named 'allowedAdapters' to determine
+ which database adapter objects to show. This property must be
+ of type "lines" so we get a sequence of connection IDs.
+ """
+ ids = ZSQLConnectionIDs(self)
+
+ # We are allowing Acquisition to find the attribute on objects
+ # higher up in the hierarchy. We do not check on the ZSQL method
+ # itself to prevent abuse.
+ if isinstance(self, RestrictedZSQLMethod):
+ self = aq_parent(aq_inner(self))
+
+ allowedAdapters = getattr(self, 'allowedAdapters', [])
+
+ if len(allowedAdapters) > 0:
+ ids = [x for x in ids if x[0] in allowedAdapters]
+
+ return tuple(ids)
+
+
+addRestrictedZSQLMethodForm = DTMLFile('www/add', globals())
+def manage_addRestrictedZSQLMethod( self
+ , id
+ , title
+ , connection_id
+ , arguments=''
+ , template=''
+ , REQUEST=None
+ ):
+ """ add a RestrictedZSQLMethod into the system """
+ rsm = RestrictedZSQLMethod( id
+ , title
+ , connection_id
+ , arguments
+ , template
+ )
+ self._setObject(id, rsm)
+
+ if REQUEST is not None:
+ ret_url = '%s/%s/manage_main' % (self.absolute_url(), id)
+ REQUEST['RESPONSE'].redirect(ret_url)
+
+
+class RestrictedZSQLMethod(SQL):
+ """ A RestrictedZSQLMethod class """
+ security = ClassSecurityInfo()
+ meta_type = 'Restricted ZSQL method'
+
+ manage = manage_main = DTMLFile('www/edit', globals())
+ manage_main._setName('manage_main')
+
+InitializeClass(RestrictedZSQLMethod)
diff --git a/VERSION.txt b/VERSION.txt
new file mode 100644
index 0000000..b63ba69
--- /dev/null
+++ b/VERSION.txt
@@ -0,0 +1 @@
+0.9
diff --git a/__init__.py b/__init__.py
new file mode 100644
index 0000000..54b7c68
--- /dev/null
+++ b/__init__.py
@@ -0,0 +1,28 @@
+#####################################################################
+#
+# RestrictedZSQLMethods Initialization
+#
+# This software is governed by a license. See
+# LICENSE.txt for the terms of this license.
+#
+#####################################################################
+__version__='$Revision: 1145 $'[11:-2]
+
+from RestrictedZSQLMethod import restrictedSQLConnectionIDs
+from RestrictedZSQLMethod import RestrictedZSQLMethod
+from RestrictedZSQLMethod import addRestrictedZSQLMethodForm
+from RestrictedZSQLMethod import manage_addRestrictedZSQLMethod
+
+def initialize(context):
+ try:
+ context.registerClass( RestrictedZSQLMethod
+ , permission='Add Restricted Database Methods'
+ , constructors=( addRestrictedZSQLMethodForm
+ , manage_addRestrictedZSQLMethod
+ )
+ , icon='www/restrictedsqlmethod.gif'
+ , legacy=[restrictedSQLConnectionIDs]
+ )
+ except:
+ import traceback; traceback.print_exc()
+
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644
index 0000000..049524c
--- /dev/null
+++ b/tests/__init__.py
@@ -0,0 +1 @@
+""" This space intentionally left blank """
diff --git a/tests/test_RestrictedZSQLMethods.py b/tests/test_RestrictedZSQLMethods.py
new file mode 100644
index 0000000..088c37f
--- /dev/null
+++ b/tests/test_RestrictedZSQLMethods.py
@@ -0,0 +1,119 @@
+#####################################################################
+#
+# RestrictedZSQLMethods ZSQLMethods with limited connections
+#
+# This software is governed by a license. See
+# LICENSE.txt for the terms of this license.
+#
+#####################################################################
+"""RestrictedZSQLMethods tests.
+
+$Id: test_RestrictedZSQLMethods.py 1275 2005-12-12 18:49:34Z jens $
+"""
+
+import unittest
+import Testing
+try:
+ import Zope2
+except ImportError:
+ import Zope as Zope2
+Zope2.startup()
+
+try:
+ import transaction
+ get_transaction = transaction.get
+except ImportError:
+ pass
+
+from OFS.Folder import Folder
+from Products.ZGadflyDA.DA import manage_addZGadflyConnection
+
+from Products.RestrictedZSQLMethods.RestrictedZSQLMethod \
+ import RestrictedZSQLMethod
+from Products.RestrictedZSQLMethods.RestrictedZSQLMethod \
+ import manage_addRestrictedZSQLMethod
+
+
+class RestrictedZSQLMethodsTests(unittest.TestCase):
+
+ def setUp(self):
+ self.root = Folder('root')
+
+ for i in range(3):
+ conn_id = 'conn_%i' % i
+ manage_addZGadflyConnection( self.root
+ , conn_id
+ , conn_id
+ , conn_id
+ )
+
+ folder_id = 'subfolder'
+ subfolder = Folder(folder_id)
+ self.root._setObject(folder_id, subfolder)
+ folder = getattr(self.root, folder_id)
+ manage_addRestrictedZSQLMethod( folder
+ , 'testing'
+ , 'testing'
+ , conn_id
+ )
+ self.zsql = self.root.subfolder.testing
+
+ def tearDown(self):
+ get_transaction().abort()
+
+ def test_NoProperty(self):
+ # The property cannot be found - all connection IDs are available
+ available = [x[0] for x in self.zsql.restrictedSQLConnectionIDs()]
+ available.sort()
+
+ self.assertEqual(available, ['conn_0', 'conn_1', 'conn_2'])
+
+ def test_PropertyManagerProperty(self):
+ # Set the property as a PropertyManager-style property
+ self.root.manage_addProperty( 'allowedAdapters'
+ , 'conn_0\nconn_2\n'
+ , 'lines'
+ )
+ available = [x[0] for x in self.zsql.restrictedSQLConnectionIDs()]
+ available.sort()
+ self.assertEqual(available, ['conn_0', 'conn_2'])
+
+ self.root.manage_changeProperties(allowedAdapters='')
+ available = [x[0] for x in self.zsql.restrictedSQLConnectionIDs()]
+ available.sort()
+ self.assertEqual(available, ['conn_0', 'conn_1', 'conn_2'])
+
+ def test_Attribute(self):
+ # Set the property as a normal attribute
+ self.root.allowedAdapters = ('conn_1', 'conn_2')
+ available = [x[0] for x in self.zsql.restrictedSQLConnectionIDs()]
+ available.sort()
+ self.assertEqual(available, ['conn_1', 'conn_2'])
+
+ self.root.allowedAdapters = ['conn_1', 'conn_0']
+ available = [x[0] for x in self.zsql.restrictedSQLConnectionIDs()]
+ available.sort()
+ self.assertEqual(available, ['conn_0', 'conn_1'])
+
+ self.root.allowedAdapters = []
+ available = [x[0] for x in self.zsql.restrictedSQLConnectionIDs()]
+ available.sort()
+ self.assertEqual(available, ['conn_0', 'conn_1', 'conn_2'])
+
+ def test_PropertyOnSQLMethod(self):
+ # Setting the magic property on the Restricted ZSQL Method
+ # itself has no effect.
+ self.root.allowedAdapters = ('conn_1', 'conn_2')
+ self.zsql.allowedAdapters = ('conn_0', 'conn_1', 'conn_2')
+ available = [x[0] for x in self.zsql.restrictedSQLConnectionIDs()]
+ available.sort()
+ self.assertEqual(available, ['conn_1', 'conn_2'])
+
+
+def test_suite():
+ suite = unittest.makeSuite(RestrictedZSQLMethodsTests)
+ return suite
+
+if __name__ == '__main__':
+ unittest.main()
+
diff --git a/www/add.dtml b/www/add.dtml
new file mode 100644
index 0000000..d0d0ee5
--- /dev/null
+++ b/www/add.dtml
@@ -0,0 +1,105 @@
+<dtml-var manage_page_header>
+
+<dtml-var "manage_form_title(this(), _,
+ form_title='Add Restricted SQL Method',
+ help_product='ZSQLMethods',
+ help_topic='Z-SQL-Method_Add.stx'
+ )">
+
+<dtml-if restrictedSQLConnectionIDs>
+<p class="form-help">
+A SQL Method allows you to access a SQL database. For more information see
+the <a href="http://www.zope.org/Documentation/Guides/ZSQL">Z SQL Methods
+User's Guide</a>.
+</p>
+
+<p class="form-help">
+In the form below <EM>connection id</EM> is the name of the SQL Database
+Connection to use. <EM>Arguments</EM> is a list of variables which the
+SQL Method accepts. <EM>Query template</EM> is a template of the SQL
+statement which the SQL Method will execute.
+</p>
+
+<form action="manage_addRestrictedZSQLMethod" method="post">
+<table cellspacing="0" cellpadding="2" border="0">
+ <tr>
+ <td align="left" valign="top">
+ <div class="form-label">
+ Id
+ </div>
+ </td>
+ <td align="left" valign="top">
+ <input type="text" name="id" size="40" value="" />
+ </td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">
+ <div class="form-optional">
+ Title
+ </div>
+ </td>
+ <td align="left" valign="top">
+ <input type="text" name="title" size="40" />
+ </td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">
+ <div class="form-label">
+ Connection Id
+ </div>
+ </td>
+ <td align="left" valign="top">
+ <div class="form-element">
+ <select name="connection_id">
+ <dtml-in restrictedSQLConnectionIDs>
+ <option value="&dtml-sequence-item;">
+ &dtml-sequence-key;</option>
+ </dtml-in>
+ </select>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">
+ <div class="form-optional">
+ Arguments
+ </div>
+ </td>
+ <td align="left" valign="top">
+ <textarea name="arguments" cols="40" rows="4"></textarea>
+ </td>
+ </tr>
+ <tr>
+ <td align="left" valign="top" colspan="2">
+ <span class="form-label">Query Template</span>
+ <br />
+ <div style="width: 100%;">
+ <textarea style="width: 100%;" name="template:text" rows="9" cols="60"
+ wrap="off">select * from data</textarea></div>
+ </td>
+ </tr>
+ <tr>
+ <td align="left" valign="top" colspan="2">
+ <div class="form-element">
+ <input class="form-element" type="submit" name="submit"
+ value=" Add " />
+ <input class="form-element" type="submit" name="submit"
+ value=" Add and Edit " />
+ <input class="form-element" type="submit" name="submit"
+ value=" Add and Test " />
+ </div>
+ </td>
+ </tr>
+</table>
+</form>
+
+
+<dtml-else>
+<p class="form-text">
+There are no SQL database connections. You need to add a Zope
+SQL database connection before you can create a Zope SQL Method.
+</p>
+
+</dtml-if>
+
+<dtml-var manage_page_footer>
diff --git a/www/edit.dtml b/www/edit.dtml
new file mode 100644
index 0000000..61079a2
--- /dev/null
+++ b/www/edit.dtml
@@ -0,0 +1,108 @@
+<dtml-var manage_page_header>
+<dtml-var manage_tabs>
+
+<dtml-if restrictedSQLConnectionIDs>
+
+<form action="manage_edit" method="POST">
+<table cellpadding="2" cellspacing="0" width="100%" border="0">
+<tr>
+ <td align="left" valign="top">
+ <div class="form-optional">
+ Title
+ </div>
+ </td>
+ <td align="left" valign="top">
+ <input type="text" name="title" size="40" value="<dtml-if
+ title>&dtml-title;</dtml-if>">
+ </td>
+</tr>
+ <tr>
+ <td align="left" valign="top">
+ <div class="form-label">
+ Connection Id
+ </div>
+ </td>
+ <td align="left" valign="top">
+ <div class="form-element">
+ <select name="connection_id">
+ <dtml-in restrictedSQLConnectionIDs>
+ <option value="&dtml-sequence-item;"<dtml-if
+ expr="connection_id==_vars['sequence-item']">
+ selected</dtml-if>>
+ &dtml-sequence-key;</option>
+ </dtml-in>
+ </select>
+ <dtml-if connectionIsValid>
+ <dtml-if connected><dtml-else>
+ <p style="{color:red;}">
+ <strong>Warning:</strong>
+ The database connection used by this method is closed.
+ </p>
+ </dtml-if>
+ <dtml-else>
+ <p style="{color:red;}">
+ <strong>Warning:</strong>
+ The selected database connection (&dtml-connection_id;)
+ cannot be found!
+ </p>
+ </dtml-if>
+ </div>
+ </td>
+ </tr>
+ <tr>
+ <td align="left" valign="top">
+ <div class="form-optional">
+ Arguments
+ </div>
+ </td>
+ <td align="left" valign="top">
+ <textarea name="arguments" cols="40" rows="4">&dtml-arguments_src;</textarea>
+ </td>
+ </tr>
+ <tr>
+ <td align="left" valign="top" colspan="2">
+ <dtml-let cols="REQUEST.get('dtpref_cols', '100%')"
+ rows="REQUEST.get('dtpref_rows', '20')">
+ <dtml-if expr="cols[-1]=='%'">
+ <textarea name="template:text" wrap="off" style="width: &dtml-cols;;"
+ <dtml-else>
+ <textarea name="template:text" wrap="off" cols="&dtml-cols;"
+ </dtml-if>
+ rows="&dtml-rows;">&dtml-src;</textarea>
+ </dtml-let>
+ </td>
+ </tr>
+
+<tr>
+ <td align="left" valign="top" colspan="2">
+ <div class="form-element">
+ <dtml-if wl_isLocked>
+ <em>Locked by WebDAV</em>
+ <dtml-else>
+ <input class="form-element" type="submit" name="SUBMIT"
+ value="Save Changes">
+ <input class="form-element" type="submit" name="SUBMIT"
+ value="Change and Test">
+ </dtml-if wl_isLocked>
+ <br />
+ <input class="form-element" type="submit" name="SUBMIT" value="Taller">
+ <input class="form-element" type="submit" name="SUBMIT" value="Shorter">
+ <input class="form-element" type="submit" name="SUBMIT" value="Wider">
+ <input class="form-element" type="submit" name="SUBMIT" value="Narrower">
+ </div>
+ </td>
+</tr>
+</table>
+</form>
+
+
+<dtml-else>
+<p class="form-help">
+There are no SQL database connections. You need to add a Zope SQL
+database connection before you can edit a Zope SQL Method.
+</p>
+</dtml-if>
+
+<dtml-var manage_page_footer>
+
+
diff --git a/www/restrictedsqlmethod.gif b/www/restrictedsqlmethod.gif
new file mode 100644
index 0000000..9cabfba
--- /dev/null
+++ b/www/restrictedsqlmethod.gif
Binary files differ