Commit 15b92e7c authored by Yorick Peterse's avatar Yorick Peterse

Use has_table_privilege for TRIGGER on PostgreSQL

This fixes https://gitlab.com/gitlab-org/gitlab-ce/issues/38634.
parent fa037e7c
---
title: Use has_table_privilege for TRIGGER on PostgreSQL
merge_request:
author:
type: fixed
...@@ -12,30 +12,40 @@ module Gitlab ...@@ -12,30 +12,40 @@ module Gitlab
# Returns true if the current user can create and execute triggers on the # Returns true if the current user can create and execute triggers on the
# given table. # given table.
def self.create_and_execute_trigger?(table) def self.create_and_execute_trigger?(table)
priv = if Database.postgresql?
if Database.postgresql? # We _must not_ use quote_table_name as this will produce double
where(privilege_type: 'TRIGGER', table_name: table) # quotes on PostgreSQL and for "has_table_privilege" we need single
.where('grantee = user') # quotes.
else quoted_table = connection.quote(table)
queries = [
Grant.select(1)
.from('information_schema.user_privileges')
.where("PRIVILEGE_TYPE = 'SUPER'")
.where("GRANTEE = CONCAT('\\'', REPLACE(CURRENT_USER(), '@', '\\'@\\''), '\\'')"),
Grant.select(1) begin
.from('information_schema.schema_privileges') from(nil)
.where("PRIVILEGE_TYPE = 'TRIGGER'") .pluck("has_table_privilege(#{quoted_table}, 'TRIGGER')")
.where('TABLE_SCHEMA = ?', Gitlab::Database.database_name) .first
.where("GRANTEE = CONCAT('\\'', REPLACE(CURRENT_USER(), '@', '\\'@\\''), '\\'')") rescue ActiveRecord::StatementInvalid
] # This error is raised when using a non-existing table name. In this
# case we just want to return false as a user technically can't
# create triggers for such a table.
false
end
else
queries = [
Grant.select(1)
.from('information_schema.user_privileges')
.where("PRIVILEGE_TYPE = 'SUPER'")
.where("GRANTEE = CONCAT('\\'', REPLACE(CURRENT_USER(), '@', '\\'@\\''), '\\'')"),
union = SQL::Union.new(queries).to_sql Grant.select(1)
.from('information_schema.schema_privileges')
.where("PRIVILEGE_TYPE = 'TRIGGER'")
.where('TABLE_SCHEMA = ?', Gitlab::Database.database_name)
.where("GRANTEE = CONCAT('\\'', REPLACE(CURRENT_USER(), '@', '\\'@\\''), '\\'')")
]
Grant.from("(#{union}) privs") union = SQL::Union.new(queries).to_sql
end
priv.any? Grant.from("(#{union}) privs").any?
end
end end
end end
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment