Attached patch fixes fdo#47937, namely that if the current user has
privileges to UPDATE or INSERT only some columns of table tbl, then
the Base UI locks the whole tbl for insertion or editing, and does not
let the user add new rows, nor edit the columns (s)he *is* allowed to
insert / edit.
This patch may look like an ugly hack, but not that much:
See
http://docs.oracle.com/javase/6/docs/api/java/sql/DatabaseMetaData.html#getTablePrivileges(java.lang.String,%20java.lang.String,%20java.lang.String)
which says:
Note that a table privilege applies to one or more columns in the
table. It would be wrong to assume that this privilege applies to all
columns (this may be true for some systems but is not true for all.)
Which means that at least some JDBC drivers will return a privilege
(for the table) even when the privilege is only over one column among
several. So this patch actually unifies the situation "manually" so
that Base works well with all drivers: those that list a privilege as
soon as one column, and those that list a privilege only if all
columns (and then give the detailed privileges in
getColumnPrivileges).
Future enhancement: selectively lock columns / controls depending on
privileges on the underlying column.
Please apply to libreoffice-3-5.
--
Lionel
From ff325831dd327761ba9985f5f657dc9716ff4df6 Mon Sep 17 00:00:00 2001
From: Lionel Elie Mamane <lionel@mamane.lu>
Date: Tue, 27 Mar 2012 10:49:49 +0200
Subject: [PATCH] fdo#47937: copy column privileges into table privileges
---
connectivity/source/commontools/dbtools2.cxx | 73 ++++++++++++++++++++++----
1 files changed, 62 insertions(+), 11 deletions(-)
diff --git a/connectivity/source/commontools/dbtools2.cxx
b/connectivity/source/commontools/dbtools2.cxx
index 63492b4..6d37f99 100644
--- a/connectivity/source/commontools/dbtools2.cxx
+++ b/connectivity/source/commontools/dbtools2.cxx
@@ -675,19 +675,20 @@ sal_Int32 getTablePrivileges(const Reference< XDatabaseMetaData>& _xMetaData,
Reference< XResultSet > xPrivileges = _xMetaData->getTablePrivileges(aVal, _sSchema,
_sTable);
Reference< XRow > xCurrentRow(xPrivileges, UNO_QUERY);
+ const ::rtl::OUString sUserWorkingFor = _xMetaData->getUserName();
+ static const ::rtl::OUString sSELECT( RTL_CONSTASCII_USTRINGPARAM( "SELECT" ));
+ static const ::rtl::OUString sINSERT( RTL_CONSTASCII_USTRINGPARAM( "INSERT" ));
+ static const ::rtl::OUString sUPDATE( RTL_CONSTASCII_USTRINGPARAM( "UPDATE" ));
+ static const ::rtl::OUString sDELETE( RTL_CONSTASCII_USTRINGPARAM( "DELETE" ));
+ static const ::rtl::OUString sREAD( RTL_CONSTASCII_USTRINGPARAM( "READ" ));
+ static const ::rtl::OUString sCREATE( RTL_CONSTASCII_USTRINGPARAM( "CREATE" ));
+ static const ::rtl::OUString sALTER( RTL_CONSTASCII_USTRINGPARAM( "ALTER" ));
+ static const ::rtl::OUString sREFERENCE( RTL_CONSTASCII_USTRINGPARAM( "REFERENCE" ));
+ static const ::rtl::OUString sDROP( RTL_CONSTASCII_USTRINGPARAM( "DROP" ));
+
if ( xCurrentRow.is() )
{
- ::rtl::OUString sUserWorkingFor = _xMetaData->getUserName();
- static const ::rtl::OUString sSELECT( RTL_CONSTASCII_USTRINGPARAM( "SELECT" ));
- static const ::rtl::OUString sINSERT( RTL_CONSTASCII_USTRINGPARAM( "INSERT" ));
- static const ::rtl::OUString sUPDATE( RTL_CONSTASCII_USTRINGPARAM( "UPDATE" ));
- static const ::rtl::OUString sDELETE( RTL_CONSTASCII_USTRINGPARAM( "DELETE" ));
- static const ::rtl::OUString sREAD( RTL_CONSTASCII_USTRINGPARAM( "READ" ));
- static const ::rtl::OUString sCREATE( RTL_CONSTASCII_USTRINGPARAM( "CREATE" ));
- static const ::rtl::OUString sALTER( RTL_CONSTASCII_USTRINGPARAM( "ALTER" ));
- static const ::rtl::OUString sREFERENCE( RTL_CONSTASCII_USTRINGPARAM( "REFERENCE" ));
- static const ::rtl::OUString sDROP( RTL_CONSTASCII_USTRINGPARAM( "DROP" ));
- // after creation the set is positioned before the first record, per definitionem
+ // after creation the set is positioned before the first record, per definition
#ifdef DBG_UTIL
Reference< XResultSetMetaDataSupplier > xSup(xPrivileges,UNO_QUERY);
if ( xSup.is() )
@@ -744,6 +745,56 @@ sal_Int32 getTablePrivileges(const Reference< XDatabaseMetaData>& _xMetaData,
}
}
disposeComponent(xPrivileges);
+
+ // Some drivers put a table privilege as soon as any column has the privilege,
+ // some drivers only if all columns have the privilege.
+ // To unifiy the situation, collect column privileges here, too.
+ Reference< XResultSet > xColumnPrivileges = _xMetaData->getColumnPrivileges(aVal,
_sSchema, _sTable, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("%")));
+ Reference< XRow > xColumnCurrentRow(xColumnPrivileges, UNO_QUERY);
+ if ( xColumnCurrentRow.is() )
+ {
+ // after creation the set is positioned before the first record, per definition
+ ::rtl::OUString sPrivilege, sGrantee;
+ while ( xColumnPrivileges->next() )
+ {
+#ifdef DBG_UTIL
+ ::rtl::OUString sCat, sSchema, sTableName, sColumnName, sGrantor, sGrantable;
+ sCat = xColumnCurrentRow->getString(1);
+ sSchema = xColumnCurrentRow->getString(2);
+ sTableName = xColumnCurrentRow->getString(3);
+ sColumnName = xColumnCurrentRow->getString(4);
+ sGrantor = xColumnCurrentRow->getString(5);
+#endif
+ sGrantee = xColumnCurrentRow->getString(6);
+ sPrivilege = xColumnCurrentRow->getString(7);
+#ifdef DBG_UTIL
+ sGrantable = xColumnCurrentRow->getString(8);
+#endif
+
+ if (!sUserWorkingFor.equalsIgnoreAsciiCase(sGrantee))
+ continue;
+
+ if (sPrivilege.equalsIgnoreAsciiCase(sSELECT))
+ nPrivileges |= Privilege::SELECT;
+ else if (sPrivilege.equalsIgnoreAsciiCase(sINSERT))
+ nPrivileges |= Privilege::INSERT;
+ else if (sPrivilege.equalsIgnoreAsciiCase(sUPDATE))
+ nPrivileges |= Privilege::UPDATE;
+ else if (sPrivilege.equalsIgnoreAsciiCase(sDELETE))
+ nPrivileges |= Privilege::DELETE;
+ else if (sPrivilege.equalsIgnoreAsciiCase(sREAD))
+ nPrivileges |= Privilege::READ;
+ else if (sPrivilege.equalsIgnoreAsciiCase(sCREATE))
+ nPrivileges |= Privilege::CREATE;
+ else if (sPrivilege.equalsIgnoreAsciiCase(sALTER))
+ nPrivileges |= Privilege::ALTER;
+ else if (sPrivilege.equalsIgnoreAsciiCase(sREFERENCE))
+ nPrivileges |= Privilege::REFERENCE;
+ else if (sPrivilege.equalsIgnoreAsciiCase(sDROP))
+ nPrivileges |= Privilege::DROP;
+ }
+ }
+ disposeComponent(xColumnPrivileges);
}
catch(const SQLException& e)
{
--
1.7.7.3
Context
- [PATCH] [REVIEW:3-5] fdo#47937 UI locks read-only when partial write privilege · Lionel Elie Mamane
Privacy Policy |
Impressum (Legal Info) |
Copyright information: Unless otherwise specified, all text and images
on this website are licensed under the
Creative Commons Attribution-Share Alike 3.0 License.
This does not include the source code of LibreOffice, which is
licensed under the Mozilla Public License (
MPLv2).
"LibreOffice" and "The Document Foundation" are
registered trademarks of their corresponding registered owners or are
in actual use as trademarks in one or more countries. Their respective
logos and icons are also subject to international copyright laws. Use
thereof is explained in our
trademark policy.