Skip to content

Commit

Permalink
Merge pull request #612 from lavoiesl/identifier-quoting
Browse files Browse the repository at this point in the history
Reworked all identifier quoting detections
  • Loading branch information
igalic committed Dec 10, 2014
2 parents 8e24162 + 60838a5 commit aeb5ae5
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 15 deletions.
23 changes: 17 additions & 6 deletions lib/puppet/type/mysql_grant.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,24 @@ def initialize(*args)
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

Expand Down
25 changes: 17 additions & 8 deletions lib/puppet/type/mysql_user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,28 @@
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

Expand Down
10 changes: 9 additions & 1 deletion spec/unit/puppet/type/mysql_user_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,15 @@
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

0 comments on commit aeb5ae5

Please sign in to comment.