Use has_table_privilege for TRIGGER on PostgreSQL

This fixes https://gitlab.com/gitlab-org/gitlab-ce/issues/38634.
This commit is contained in:
Yorick Peterse 2018-01-22 13:43:18 +01:00
parent fa037e7c5f
commit 15b92e7cc2
No known key found for this signature in database
GPG Key ID: EDD30D2BEB691AC9
2 changed files with 36 additions and 21 deletions

View File

@ -0,0 +1,5 @@
---
title: Use has_table_privilege for TRIGGER on PostgreSQL
merge_request:
author:
type: fixed

View File

@ -12,30 +12,40 @@ module Gitlab
# Returns true if the current user can create and execute triggers on the
# given table.
def self.create_and_execute_trigger?(table)
priv =
if Database.postgresql?
where(privilege_type: 'TRIGGER', table_name: table)
.where('grantee = user')
else
queries = [
Grant.select(1)
.from('information_schema.user_privileges')
.where("PRIVILEGE_TYPE = 'SUPER'")
.where("GRANTEE = CONCAT('\\'', REPLACE(CURRENT_USER(), '@', '\\'@\\''), '\\'')"),
if Database.postgresql?
# We _must not_ use quote_table_name as this will produce double
# quotes on PostgreSQL and for "has_table_privilege" we need single
# quotes.
quoted_table = connection.quote(table)
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(), '@', '\\'@\\''), '\\'')")
]
union = SQL::Union.new(queries).to_sql
Grant.from("(#{union}) privs")
begin
from(nil)
.pluck("has_table_privilege(#{quoted_table}, 'TRIGGER')")
.first
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(), '@', '\\'@\\''), '\\'')"),
priv.any?
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(), '@', '\\'@\\''), '\\'')")
]
union = SQL::Union.new(queries).to_sql
Grant.from("(#{union}) privs").any?
end
end
end
end