diff options
author | Julien Nabet <serval2412@yahoo.fr> | 2023-12-02 21:21:27 +0100 |
---|---|---|
committer | Julien Nabet <serval2412@yahoo.fr> | 2023-12-02 22:45:34 +0100 |
commit | 7265820661325578011ffd336316ddfa38c511c2 (patch) | |
tree | 4156d5b9eb22a2588d47ab5a151ef3132389e2ad /connectivity/source/drivers | |
parent | 18ff318c759aa228e317cf916f39bd6bf2d8dfb4 (diff) |
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 <serval2412@yahoo.fr>
Tested-by: Jenkins
Diffstat (limited to 'connectivity/source/drivers')
3 files changed, 151 insertions, 10 deletions
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:: |