From 33734ce5f9fc614fd8edd1b1a6bde5f91a099ec7 Mon Sep 17 00:00:00 2001 From: mat02 Date: Mon, 19 Jul 2021 17:56:42 +0200 Subject: [PATCH] Fix for FB2.x - Table permissions check cannot return constants --- src/metabase/driver/firebird.clj | 55 ++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 10 deletions(-) diff --git a/src/metabase/driver/firebird.clj b/src/metabase/driver/firebird.clj index fb5abba..622b13b 100644 --- a/src/metabase/driver/firebird.clj +++ b/src/metabase/driver/firebird.clj @@ -8,16 +8,20 @@ [java-time :as t] [metabase.driver :as driver] [metabase.driver.common :as driver.common] + ;; [metabase.driver.sql-jdbc.sync.describe-database :as sql-jdbc.sync.describe-database] [metabase.driver.sql-jdbc [common :as sql-jdbc.common] [connection :as sql-jdbc.conn] [sync :as sql-jdbc.sync]] + [metabase.driver.sql-jdbc.sync.common :as sql-jdbc.sync.common] [metabase.driver.sql.query-processor :as sql.qp] [metabase.util [honeysql-extensions :as hx]] [metabase.util.ssh :as ssh]) (:import [java.sql DatabaseMetaData Time] - [java.time LocalDate LocalDateTime LocalTime OffsetDateTime OffsetTime ZonedDateTime])) + [java.time LocalDate LocalDateTime LocalTime OffsetDateTime OffsetTime ZonedDateTime] + [java.sql Connection DatabaseMetaData ResultSet])) + (driver/register! :firebird, :parent :sql-jdbc) @@ -81,6 +85,37 @@ items (* items (dec page)))])) + +;; When selecting constants Firebird doesn't check privileges, we have to select all fields +(defn simple-select-probe-query + [driver schema table] + {:pre [(string? table)]} + (let [honeysql {:select [:*] + :from [(sql.qp/->honeysql driver (hx/identifier :table schema table))] + :where [:not= 1 1]} + honeysql (sql.qp/apply-top-level-clause driver :limit honeysql {:limit 0})] + (sql.qp/format-honeysql driver honeysql))) + +(defn- execute-select-probe-query + [driver ^Connection conn [sql & params]] + {:pre [(string? sql)]} + (with-open [stmt (sql-jdbc.sync.common/prepare-statement driver conn sql params)] + ;; attempting to execute the SQL statement will throw an Exception if we don't have permissions; otherwise it will + ;; truthy wheter or not it returns a ResultSet, but we can ignore that since we have enough info to proceed at + ;; this point. + (.execute stmt))) + +(defmethod sql-jdbc.sync/have-select-privilege? :sql-jdbc + [driver conn table-schema table-name] + ;; Query completes = we have SELECT privileges + ;; Query throws some sort of no permissions exception = no SELECT privileges + (let [sql-args (simple-select-probe-query driver table-schema table-name)] + (try + (execute-select-probe-query driver conn sql-args) + true + (catch Throwable _ + false)))) + (defmethod sql-jdbc.sync/active-tables :firebird [& args] (apply sql-jdbc.sync/post-filtered-active-tables args)) @@ -161,15 +196,15 @@ (defmethod sql.qp/->honeysql [:firebird :substring] [driver [_ arg start length]] (let [col-name (hformat/to-sql (sql.qp/->honeysql driver arg))] - (if length - (reify - hformat/ToSql - (to-sql [_] - (str "substring(" col-name " FROM " start " FOR " length ")"))) - (reify - hformat/ToSql - (to-sql [_] - (str "substring(" col-name " FROM " start ")")))))) + (if length + (reify + hformat/ToSql + (to-sql [_] + (str "substring(" col-name " FROM " start " FOR " length ")"))) + (reify + hformat/ToSql + (to-sql [_] + (str "substring(" col-name " FROM " start ")")))))) (defmethod sql.qp/add-interval-honeysql-form :firebird [driver hsql-form amount unit] (if (= unit :quarter)