Fix TRIGGER checks for MySQL
This ensures we can check if the user has TRIGGER permissions without querying restricted tables. Thanks to Steve Norman (https://gitlab.com/stevenorman) for helping out with this merge request. Fixes https://gitlab.com/gitlab-org/gitlab-ce/issues/38372
This commit is contained in:
parent
c71cf908cd
commit
60526a5291
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Fix TRIGGER checks for MySQL
|
||||||
|
merge_request:
|
||||||
|
author:
|
||||||
|
type: fixed
|
|
@ -6,15 +6,7 @@ module Gitlab
|
||||||
if Database.postgresql?
|
if Database.postgresql?
|
||||||
'information_schema.role_table_grants'
|
'information_schema.role_table_grants'
|
||||||
else
|
else
|
||||||
'mysql.user'
|
'information_schema.schema_privileges'
|
||||||
end
|
|
||||||
|
|
||||||
def self.scope_to_current_user
|
|
||||||
if Database.postgresql?
|
|
||||||
where('grantee = user')
|
|
||||||
else
|
|
||||||
where("CONCAT(User, '@', Host) = current_user()")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# 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
|
||||||
|
@ -23,11 +15,27 @@ module Gitlab
|
||||||
priv =
|
priv =
|
||||||
if Database.postgresql?
|
if Database.postgresql?
|
||||||
where(privilege_type: 'TRIGGER', table_name: table)
|
where(privilege_type: 'TRIGGER', table_name: table)
|
||||||
|
.where('grantee = user')
|
||||||
else
|
else
|
||||||
where(Trigger_priv: 'Y')
|
queries = [
|
||||||
|
Grant.select(1)
|
||||||
|
.from('information_schema.user_privileges')
|
||||||
|
.where("PRIVILEGE_TYPE = 'SUPER'")
|
||||||
|
.where("GRANTEE = CONCAT('\\'', REPLACE(CURRENT_USER(), '@', '\\'@\\''), '\\'')"),
|
||||||
|
|
||||||
|
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")
|
||||||
end
|
end
|
||||||
|
|
||||||
priv.scope_to_current_user.any?
|
priv.any?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,16 +1,6 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
describe Gitlab::Database::Grant do
|
describe Gitlab::Database::Grant do
|
||||||
describe '.scope_to_current_user' do
|
|
||||||
it 'scopes the relation to the current user' do
|
|
||||||
user = Gitlab::Database.username
|
|
||||||
column = Gitlab::Database.postgresql? ? :grantee : :User
|
|
||||||
names = described_class.scope_to_current_user.pluck(column).uniq
|
|
||||||
|
|
||||||
expect(names).to eq([user])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '.create_and_execute_trigger' do
|
describe '.create_and_execute_trigger' do
|
||||||
it 'returns true when the user can create and execute a trigger' do
|
it 'returns true when the user can create and execute a trigger' do
|
||||||
# We assume the DB/user is set up correctly so that triggers can be
|
# We assume the DB/user is set up correctly so that triggers can be
|
||||||
|
@ -18,13 +8,11 @@ describe Gitlab::Database::Grant do
|
||||||
expect(described_class.create_and_execute_trigger?('users')).to eq(true)
|
expect(described_class.create_and_execute_trigger?('users')).to eq(true)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'returns false when the user can not create and/or execute a trigger' do
|
it 'returns false when the user can not create and/or execute a trigger', :postgresql do
|
||||||
allow(described_class).to receive(:scope_to_current_user)
|
# In case of MySQL the user may have SUPER permissions, making it
|
||||||
.and_return(described_class.none)
|
# impossible to have `false` returned when running tests; hence we only
|
||||||
|
# run these tests on PostgreSQL.
|
||||||
result = described_class.create_and_execute_trigger?('kittens')
|
expect(described_class.create_and_execute_trigger?('foo')).to eq(false)
|
||||||
|
|
||||||
expect(result).to eq(false)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue