Reworked all identifier quoting detections

Otherwise, trying to manage `debian-sys-maint` will fail miserably, quoted or not.

Fixes #609
This commit is contained in:
Sébastien Lavoie 2014-11-26 14:46:39 -05:00
parent f235f34cab
commit 60838a5837
3 changed files with 43 additions and 15 deletions

View file

@ -60,13 +60,24 @@ Puppet::Type.newtype(:mysql_grant) do
newproperty(:user) do
desc 'User to operate on.'
validate do |value|
# https://dev.mysql.com/doc/refman/5.1/en/account-names.html
# Regex should problably be more like this: /^[`'"]?[^`'"]*[`'"]?@[`'"]?[\w%\.]+[`'"]?$/
raise(ArgumentError, "Invalid user #{value}") unless value =~ /[\w-]*@[\w%\.:]+/
username = value.split('@')[0]
if username.size > 16
raise ArgumentError, 'MySQL usernames are limited to a maximum of 16 characters'
# http://dev.mysql.com/doc/refman/5.5/en/identifiers.html
# If at least one special char is used, string must be quoted
# http://stackoverflow.com/questions/8055727/negating-a-backreference-in-regular-expressions/8057827#8057827
if matches = /^(['`"])((?!\1).)+\1@([\w%\.:]+)$/.match(value)
user_part = matches[2]
host_part = matches[3]
elsif matches = /^([0-9a-zA-Z$_]+)@([\w%\.:]+)$/.match(value)
user_part = matches[1]
host_part = matches[2]
elsif matches = /^(?:(?!['`"]).*)([^0-9a-zA-Z$_]).*@.+$/.match(value)
# does not start with a quote, but contains a special character
raise(ArgumentError, "Database user #{value} must be properly quoted, invalid character: '#{matches[1]}'")
else
raise(ArgumentError, "Invalid database user #{value}")
end
raise(ArgumentError, 'MySQL usernames are limited to a maximum of 16 characters') unless user_part.size <= 16
end
end

View file

@ -10,19 +10,28 @@ Puppet::Type.newtype(:mysql_user) do
desc "The name of the user. This uses the 'username@hostname' or username@hostname."
validate do |value|
# http://dev.mysql.com/doc/refman/5.5/en/identifiers.html
# Regex should problably be more like this: /^[`'"]?[^`'"]*[`'"]?@[`'"]?[\w%\.]+[`'"]?$/
# If at least one special char is used, string must be quoted
raise(ArgumentError, "Database user #{value} must be quotted as it contains special characters") if value =~ /^[^'`"].*[^0-9a-zA-Z$_].*[^'`"]@[\w%\.:]+/
raise(ArgumentError, "Invalid database user #{value}") unless value =~ /^(?:['`"][^'`"]*['`"]|[0-9a-zA-Z$_]*)@[\w%\.:]+/
username = value.split('@')[0]
if not ((username =~ /['"`]*['"`]$/ and username.size <= 18) or username.size <= 16)
raise ArgumentError, 'MySQL usernames are limited to a maximum of 16 characters'
# http://stackoverflow.com/questions/8055727/negating-a-backreference-in-regular-expressions/8057827#8057827
if matches = /^(['`"])((?:(?!\1).)+)\1@([\w%\.:]+)$/.match(value)
user_part = matches[2]
host_part = matches[3]
elsif matches = /^([0-9a-zA-Z$_]+)@([\w%\.:]+)$/.match(value)
user_part = matches[1]
host_part = matches[2]
elsif matches = /^(?:(?!['`"]).*)([^0-9a-zA-Z$_]).*@.+$/.match(value)
# does not start with a quote, but contains a special character
raise(ArgumentError, "Database user #{value} must be properly quoted, invalid character: '#{matches[1]}'")
else
raise(ArgumentError, "Invalid database user #{value}")
end
raise(ArgumentError, 'MySQL usernames are limited to a maximum of 16 characters') if user_part.size > 16
end
munge do |value|
user_part, host_part = value.split('@')
"#{user_part}@#{host_part.downcase}"
matches = /^((['`"]?).+\2)@([\w%\.:]+)$/.match(value)
"#{matches[1]}@#{matches[3].downcase}"
end
end

View file

@ -81,7 +81,15 @@ describe Puppet::Type.type(:mysql_user) do
it 'should fail with an unquotted username with special char' do
expect {
Puppet::Type.type(:mysql_user).new(:name => 'in-valid@localhost', :password_hash => 'pass')
}.to raise_error /Database user in-valid@localhost must be quotted/
}.to raise_error /Database user in-valid@localhost must be properly quoted, invalid character: '-'/
end
end
context 'using "misquoted@localhost' do
it 'should fail with a misquoted username is used' do
expect {
Puppet::Type.type(:mysql_user).new(:name => '"misquoted@localhost', :password_hash => 'pass')
}.to raise_error /Invalid database user "misquoted@localhost/
end
end
end