1
0
mirror of https://github.com/django/django.git synced 2024-12-23 01:25:58 +00:00

Changed Oracle test-user creation to grant privileges instead of roles

because the roles (specifically RESOURCE) are deprecated.
Also added optional support for creating views in tests, and made an
introspection test fail (rather than skip)  if a view cannot be created
due to lacking privileges.

Refs #18782

Thanks Tim Graham for review, and Josh Smeaton
This commit is contained in:
Shai Berger 2014-09-21 20:15:48 +03:00
parent a1709220d5
commit d128eac316
4 changed files with 58 additions and 7 deletions

View File

@ -3,6 +3,7 @@ import time
from django.conf import settings from django.conf import settings
from django.db.backends.creation import BaseDatabaseCreation from django.db.backends.creation import BaseDatabaseCreation
from django.db.utils import DatabaseError
from django.utils.six.moves import input from django.utils.six.moves import input
@ -172,9 +173,25 @@ class DatabaseCreation(BaseDatabaseCreation):
TEMPORARY TABLESPACE %(tblspace_temp)s TEMPORARY TABLESPACE %(tblspace_temp)s
QUOTA UNLIMITED ON %(tblspace)s QUOTA UNLIMITED ON %(tblspace)s
""", """,
"""GRANT CONNECT, RESOURCE TO %(user)s""", """GRANT CREATE SESSION,
CREATE TABLE,
CREATE SEQUENCE,
CREATE PROCEDURE,
CREATE TRIGGER
TO %(user)s""",
] ]
self._execute_statements(cursor, statements, parameters, verbosity) self._execute_statements(cursor, statements, parameters, verbosity)
# Most test-suites can be run without the create-view privilege. But some need it.
extra = "GRANT CREATE VIEW TO %(user)s"
try:
self._execute_statements(cursor, [extra], parameters, verbosity, allow_quiet_fail=True)
except DatabaseError as err:
description = str(err)
if 'ORA-01031' in description:
if verbosity >= 2:
print("Failed to grant CREATE VIEW permission to test user. This may be ok.")
else:
raise
def _execute_test_db_destruction(self, cursor, parameters, verbosity): def _execute_test_db_destruction(self, cursor, parameters, verbosity):
if verbosity >= 2: if verbosity >= 2:
@ -194,7 +211,7 @@ class DatabaseCreation(BaseDatabaseCreation):
] ]
self._execute_statements(cursor, statements, parameters, verbosity) self._execute_statements(cursor, statements, parameters, verbosity)
def _execute_statements(self, cursor, statements, parameters, verbosity): def _execute_statements(self, cursor, statements, parameters, verbosity, allow_quiet_fail=False):
for template in statements: for template in statements:
stmt = template % parameters stmt = template % parameters
if verbosity >= 2: if verbosity >= 2:
@ -202,6 +219,7 @@ class DatabaseCreation(BaseDatabaseCreation):
try: try:
cursor.execute(stmt) cursor.execute(stmt)
except Exception as err: except Exception as err:
if (not allow_quiet_fail) or verbosity >= 2:
sys.stderr.write("Failed (%s)\n" % (err)) sys.stderr.write("Failed (%s)\n" % (err))
raise raise

View File

@ -672,14 +672,37 @@ database user must have privileges to run the following commands:
* CREATE PROCEDURE * CREATE PROCEDURE
* CREATE TRIGGER * CREATE TRIGGER
To run Django's test suite, the user needs these *additional* privileges: To run a project's test suite, the user usually needs these *additional*
privileges:
* CREATE USER * CREATE USER
* DROP USER * DROP USER
* CREATE TABLESPACE * CREATE TABLESPACE
* DROP TABLESPACE * DROP TABLESPACE
* CONNECT WITH ADMIN OPTION * CREATE SESSION WITH ADMIN OPTION
* RESOURCE WITH ADMIN OPTION * CREATE TABLE WITH ADMIN OPTION
* CREATE SEQUENCE WITH ADMIN OPTION
* CREATE PROCEDURE WITH ADMIN OPTION
* CREATE TRIGGER WITH ADMIN OPTION
Note that, while the RESOURCE role has the required CREATE TABLE, CREATE
SEQUENCE, CREATE PROCEDURE and CREATE TRIGGER privileges, and a user
granted RESOURCE WITH ADMIN OPTION can grant RESOURCE, such a user cannot
grant the individual privileges (e.g. CREATE TABLE), and thus RESOURCE
WITH ADMIN OPTION is not usually sufficient for running tests.
Some test suites also create views; to run these, the user also needs
the CREATE VIEW WITH ADMIN OPTION privilege. In particular, this is needed
for Django's own test suite.
.. versionchanged:: 1.8
Prior to Django 1.8, the test user was granted the CONNECT and RESOURCE
roles, so the extra privileges required for running the test suite were
different.
All of these privileges are included in the DBA role, which is appropriate
for use on a private developer's database.
The Oracle database backend uses the ``SYS.DBMS_LOB`` package, so your user The Oracle database backend uses the ``SYS.DBMS_LOB`` package, so your user
will require execute permissions on it. It's normally accessible to all users will require execute permissions on it. It's normally accessible to all users

View File

@ -499,6 +499,16 @@ The end of upstream support periods was reached in July 2010 for Oracle 9.2,
January 2012 for Oracle 10.1, and July 2013 for Oracle 10.2. As a consequence, January 2012 for Oracle 10.1, and July 2013 for Oracle 10.2. As a consequence,
Django 1.8 sets 11.1 as the minimum Oracle version it officially supports. Django 1.8 sets 11.1 as the minimum Oracle version it officially supports.
Specific privileges used instead of roles for tests on Oracle
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Earlier versions of Django granted the CONNECT and RESOURCE roles to the test
user on Oracle. These roles have been deprecated, so Django 1.8 uses the
specific underlying privileges instead. This changes the privileges required
of the main user for running tests (unless the project is configured to avoid
creating a test user). The exact privileges required now are detailed in
:ref:`Oracle notes <oracle-notes>`.
``AbstractUser.last_login`` allows null values ``AbstractUser.last_login`` allows null values
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -43,7 +43,7 @@ class IntrospectionTests(TestCase):
'from introspection_article;') 'from introspection_article;')
except DatabaseError as e: except DatabaseError as e:
if 'insufficient privileges' in str(e): if 'insufficient privileges' in str(e):
self.skipTest("The test user has no CREATE VIEW privileges") self.fail("The test user has no CREATE VIEW privileges")
else: else:
raise raise