connectivity/source/drivers/mysqlc/mysqlc_databasemetadata.cxx |   20 +
 connectivity/source/drivers/mysqlc/mysqlc_user.cxx             |  135 
+++++++++-
 connectivity/source/drivers/mysqlc/mysqlc_user.hxx             |    6 
 3 files changed, 151 insertions(+), 10 deletions(-)

New commits:
commit 7265820661325578011ffd336316ddfa38c511c2
Author:     Julien Nabet <serval2...@yahoo.fr>
AuthorDate: Sat Dec 2 21:21:27 2023 +0100
Commit:     Julien Nabet <serval2...@yahoo.fr>
CommitDate: Sat Dec 2 22:45:34 2023 +0100

    Mysql/Mariadb: implement User and ODatabaseMetaData privileges methods
    
    User::getPrivileges
    User::getGrantablePrivileges
    + create ancillary User::findPrivilegesAndGrantPrivileges
    
    ODatabaseMetaData::getTablePrivileges
    
    Change-Id: Ib189aa121a3096aab412be68c76a3edaa11af1ec
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160247
    Reviewed-by: Julien Nabet <serval2...@yahoo.fr>
    Tested-by: Jenkins

diff --git a/connectivity/source/drivers/mysqlc/mysqlc_databasemetadata.cxx 
b/connectivity/source/drivers/mysqlc/mysqlc_databasemetadata.cxx
index 1bc934af57a9..901c9bd6dc83 100644
--- a/connectivity/source/drivers/mysqlc/mysqlc_databasemetadata.cxx
+++ b/connectivity/source/drivers/mysqlc/mysqlc_databasemetadata.cxx
@@ -1011,11 +1011,23 @@ Reference<XResultSet> SAL_CALL 
ODatabaseMetaData::getBestRowIdentifier(const Any
 }
 
 Reference<XResultSet> SAL_CALL ODatabaseMetaData::getTablePrivileges(
-    const Any& /*catalog*/, const OUString& /*schemaPattern*/, const OUString& 
/*tableNamePattern*/)
+    const Any& /* catalog */, const OUString& schemaPattern, const OUString& 
tableNamePattern)
 {
-    // TODO
-    SAL_WARN("connectivity.mysqlc", "method not implemented");
-    throw SQLException("getTablePrivileges method not implemented", *this, 
"IM001", 0, Any());
+    OUString query("SELECT TABLE_SCHEMA TABLE_CAT, "
+                   "NULL TABLE_SCHEM, "
+                   "TABLE_NAME, "
+                   "NULL GRANTOR,"
+                   "GRANTEE, "
+                   "PRIVILEGE_TYPE PRIVILEGE, "
+                   "IS_GRANTABLE "
+                   "FROM INFORMATION_SCHEMA.TABLE_PRIVILEGES "
+                   "WHERE TABLE_SCHEMA LIKE '?' "
+                   "AND TABLE_NAME='?'");
+    query = query.replaceFirst("?", schemaPattern);
+    query = query.replaceFirst("?", tableNamePattern);
+    Reference<XStatement> statement = m_rConnection.createStatement();
+    Reference<XResultSet> rs = statement->executeQuery(query);
+    return rs;
 }
 
 Reference<XResultSet> SAL_CALL ODatabaseMetaData::getCrossReference(
diff --git a/connectivity/source/drivers/mysqlc/mysqlc_user.cxx 
b/connectivity/source/drivers/mysqlc/mysqlc_user.cxx
index c1cdc1e537af..4ca048ad6cdb 100644
--- a/connectivity/source/drivers/mysqlc/mysqlc_user.cxx
+++ b/connectivity/source/drivers/mysqlc/mysqlc_user.cxx
@@ -10,6 +10,11 @@
 #include <utility>
 
 #include "mysqlc_user.hxx"
+#include <comphelper/types.hxx>
+#include <connectivity/dbtools.hxx>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/sdbcx/Privilege.hpp>
+#include <com/sun/star/sdbcx/PrivilegeObject.hpp>
 
 using namespace ::connectivity;
 using namespace ::connectivity::mysqlc;
@@ -17,6 +22,7 @@ using namespace ::connectivity::sdbcx;
 
 using namespace ::com::sun::star;
 using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::sdbcx;
 
 User::User(css::uno::Reference<css::sdbc::XConnection> xConnection)
     : OUser(true) // Case Sensitive
@@ -36,16 +42,133 @@ void User::changePassword(const OUString&, const OUString& 
/* newPassword */)
     // TODO: implement
 }
 
-sal_Int32 User::getPrivileges(const OUString&, sal_Int32)
+typedef connectivity::sdbcx::OUser_BASE OUser_BASE_RBHELPER;
+
+sal_Int32 SAL_CALL User::getPrivileges(const OUString& objName, sal_Int32 
objType)
 {
-    // TODO: implement.
-    return 0;
+    ::osl::MutexGuard aGuard(m_aMutex);
+    checkDisposed(OUser_BASE_RBHELPER::rBHelper.bDisposed);
+
+    sal_Int32 nRights, nRightsWithGrant;
+    findPrivilegesAndGrantPrivileges(objName, objType, nRights, 
nRightsWithGrant);
+    return nRights;
 }
 
-sal_Int32 User::getGrantablePrivileges(const OUString&, sal_Int32)
+void User::findPrivilegesAndGrantPrivileges(const OUString& objName, sal_Int32 
objType,
+                                            sal_Int32& nRights, sal_Int32& 
nRightsWithGrant)
 {
-    // TODO: implement.
-    return 0;
+    nRightsWithGrant = nRights = 0;
+    // first we need to create the sql stmt to select the privs
+    css::uno::Reference<XDatabaseMetaData> xMeta = 
m_xConnection->getMetaData();
+    OUString sCatalog, sSchema, sTable;
+    ::dbtools::qualifiedNameComponents(xMeta, objName, sCatalog, sSchema, 
sTable,
+                                       
::dbtools::EComposeRule::InDataManipulation);
+    css::uno::Reference<XResultSet> xRes;
+    switch (objType)
+    {
+        case css::sdbcx::PrivilegeObject::TABLE:
+        case css::sdbcx::PrivilegeObject::VIEW:
+        {
+            css::uno::Any aCatalog;
+            if (!sCatalog.isEmpty())
+                aCatalog <<= sCatalog;
+            xRes = xMeta->getTablePrivileges(aCatalog, sSchema, sTable);
+        }
+        break;
+
+        case css::sdbcx::PrivilegeObject::COLUMN:
+        {
+            css::uno::Any aCatalog;
+            if (!sCatalog.isEmpty())
+                aCatalog <<= sCatalog;
+            xRes = xMeta->getColumnPrivileges(aCatalog, sSchema, sTable, "%");
+        }
+        break;
+    }
+
+    if (!xRes.is())
+        return;
+
+    static const char sYes[] = "YES";
+
+    nRightsWithGrant = nRights = 0;
+
+    css::uno::Reference<XRow> xCurrentRow(xRes, css::uno::UNO_QUERY);
+    while (xCurrentRow.is() && xRes->next())
+    {
+        OUString sGrantee = xCurrentRow->getString(5);
+        OUString sPrivilege = xCurrentRow->getString(6);
+        OUString sGrantable = xCurrentRow->getString(7);
+
+        if (!m_Name.equalsIgnoreAsciiCase(sGrantee))
+            continue;
+
+        if (sPrivilege.equalsIgnoreAsciiCase("SELECT"))
+        {
+            nRights |= Privilege::SELECT;
+            if (sGrantable.equalsIgnoreAsciiCase(sYes))
+                nRightsWithGrant |= Privilege::SELECT;
+        }
+        else if (sPrivilege.equalsIgnoreAsciiCase("INSERT"))
+        {
+            nRights |= Privilege::INSERT;
+            if (sGrantable.equalsIgnoreAsciiCase(sYes))
+                nRightsWithGrant |= Privilege::INSERT;
+        }
+        else if (sPrivilege.equalsIgnoreAsciiCase("UPDATE"))
+        {
+            nRights |= Privilege::UPDATE;
+            if (sGrantable.equalsIgnoreAsciiCase(sYes))
+                nRightsWithGrant |= Privilege::UPDATE;
+        }
+        else if (sPrivilege.equalsIgnoreAsciiCase("DELETE"))
+        {
+            nRights |= Privilege::DELETE;
+            if (sGrantable.equalsIgnoreAsciiCase(sYes))
+                nRightsWithGrant |= Privilege::DELETE;
+        }
+        else if (sPrivilege.equalsIgnoreAsciiCase("READ"))
+        {
+            nRights |= Privilege::READ;
+            if (sGrantable.equalsIgnoreAsciiCase(sYes))
+                nRightsWithGrant |= Privilege::READ;
+        }
+        else if (sPrivilege.equalsIgnoreAsciiCase("CREATE"))
+        {
+            nRights |= Privilege::CREATE;
+            if (sGrantable.equalsIgnoreAsciiCase(sYes))
+                nRightsWithGrant |= Privilege::CREATE;
+        }
+        else if (sPrivilege.equalsIgnoreAsciiCase("ALTER"))
+        {
+            nRights |= Privilege::ALTER;
+            if (sGrantable.equalsIgnoreAsciiCase(sYes))
+                nRightsWithGrant |= Privilege::ALTER;
+        }
+        else if (sPrivilege.equalsIgnoreAsciiCase("REFERENCES"))
+        {
+            nRights |= Privilege::REFERENCE;
+            if (sGrantable.equalsIgnoreAsciiCase(sYes))
+                nRightsWithGrant |= Privilege::REFERENCE;
+        }
+        else if (sPrivilege.equalsIgnoreAsciiCase("DROP"))
+        {
+            nRights |= Privilege::DROP;
+            if (sGrantable.equalsIgnoreAsciiCase(sYes))
+                nRightsWithGrant |= Privilege::DROP;
+        }
+    }
+    ::comphelper::disposeComponent(xRes);
+}
+
+sal_Int32 SAL_CALL User::getGrantablePrivileges(const OUString& objName, 
sal_Int32 objType)
+{
+    ::osl::MutexGuard aGuard(m_aMutex);
+    checkDisposed(OUser_BASE_RBHELPER::rBHelper.bDisposed);
+
+    sal_Int32 nRights, nRightsWithGrant;
+    findPrivilegesAndGrantPrivileges(objName, objType, nRights, 
nRightsWithGrant);
+    return nRightsWithGrant;
 }
 
 //----- IRefreshableGroups ----------------------------------------------------
diff --git a/connectivity/source/drivers/mysqlc/mysqlc_user.hxx 
b/connectivity/source/drivers/mysqlc/mysqlc_user.hxx
index aad2baa214d3..d9b0435fdf78 100644
--- a/connectivity/source/drivers/mysqlc/mysqlc_user.hxx
+++ b/connectivity/source/drivers/mysqlc/mysqlc_user.hxx
@@ -34,6 +34,12 @@ public:
     // XAuthorizable
     virtual void SAL_CALL changePassword(const OUString&, const OUString& 
newPassword) override;
     virtual sal_Int32 SAL_CALL getPrivileges(const OUString&, sal_Int32) 
override;
+    // return the privileges and additional the grant rights
+    /// @throws css::sdbc::SQLException
+    /// @throws css::uno::RuntimeException
+    void findPrivilegesAndGrantPrivileges(const OUString& objName, sal_Int32 
objType,
+                                          sal_Int32& nRights, sal_Int32& 
nRightsWithGrant);
+
     virtual sal_Int32 SAL_CALL getGrantablePrivileges(const OUString&, 
sal_Int32) override;
 
     // IRefreshableGroups::

Reply via email to