Skip to content
This repository was archived by the owner on May 31, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ user "scott", "%" do
grant "USAGE"
end

on "test.*", expired: '2014/10/08', identified: "PASSWORD '*ABCDEF'" do
on "test.*", expired: '2014/10/08', identified: "*ABCDEF" do
grant "SELECT"
grant "INSERT"
end
Expand Down Expand Up @@ -141,9 +141,9 @@ end

```sh
bundle install
docker-compose up -d
docker compose up -d
bundle exec rake
# MYSQL57=1 bundle exec rake
# MYSQL80=1 bundle exec rake
```

## Similar tools
Expand Down
45 changes: 45 additions & 0 deletions compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
services:
mysql57:
container_name: mysql57
image: "mysql:5.7.42-debian"
platform: linux/amd64
ports:
- "3307:3306"
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
TZ: 'Asia/Tokyo'
restart: always
networks:
- mysql-network
mysql80:
container_name: mysql80
image: "mysql:8.0.28-debian"
platform: linux/amd64
ports:
- "3308:3306"
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: "yes"
TZ: 'Asia/Tokyo'
command: --default-authentication-plugin=mysql_native_password
restart: always
networks:
- mysql-network
ruby:
container_name: ruby
image: "ruby:2.5.7"
platform: linux/amd64
environment:
TZ: 'Asia/Tokyo'
privileged: true
tty: true
restart: always
volumes:
- type: bind
source: .
target: /home/gratan
working_dir: /home/gratan
networks:
- mysql-network
networks:
mysql-network:
driver: bridge
12 changes: 0 additions & 12 deletions docker-compose.yml

This file was deleted.

4 changes: 2 additions & 2 deletions lib/gratan/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,9 @@ def walk_options(user, host, expected_options, actual_options)
end

def walk_identified(user, host, expected_identified, actual_identified)
if actual_identified == 'PASSWORD <secret>'
if actual_identified == '<secret>'
unless @options[:ignore_password_secret]
log(:warn, "cannot change the password (`PASSWORD <secret>`)", :color => :yellow)
log(:warn, "cannot change the password (`<secret>`)", :color => :yellow)
end
elsif expected_identified != actual_identified
@driver.identify(user, host, expected_identified)
Expand Down
21 changes: 14 additions & 7 deletions lib/gratan/driver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,19 @@ def flush_privileges

def create_user(user, host, options = {})
objects = options[:objects]
identified = options[:options][:identified]
required = options[:required]
with_option = options[:with]
auth_plugin = options[:auth_plugin] || "mysql_native_password"
grant_options = options[:options]
granted = false

sql = "CREATE USER #{quote_user(user, host)}"
sql << " IDENTIFIED WITH #{auth_plugin} AS #{quote_identifier(identified)}" if identified
sql << " REQUIRE #{required}" if required
sql << " WITH #{with_option}" if with_option
update(sql)

objects.each do |object_or_regexp, object_options|
expand_object(object_or_regexp).each do |object|
grant(user, host, object, grant_options.merge(object_options))
Expand All @@ -85,7 +95,6 @@ def drop_user(user, host)

def grant(user, host, object, options)
privs = options.fetch(:privs)
identified = options[:identified]
required = options[:required]
with_option = options[:with]

Expand All @@ -95,10 +104,8 @@ def grant(user, host, object, options)
quote_user(user, host),
]

sql << " IDENTIFIED BY #{quote_identifier(identified)}" if identified
sql << " REQUIRE #{required}" if required
sql << " WITH #{with_option}" if with_option

begin
update(sql)
rescue Mysql2::Error => e
Expand All @@ -110,8 +117,8 @@ def grant(user, host, object, options)
end
end

def identify(user, host, identifier)
sql = 'GRANT USAGE ON *.* TO %s IDENTIFIED BY %s' % [
def identify(user, host, identifier, auth_plugin = "mysql_native_password")
sql = "ALTER USER %s IDENTIFIED WITH #{auth_plugin} AS %s" % [
quote_user(user, host),
quote_identifier(identifier),
]
Expand All @@ -127,7 +134,7 @@ def set_password(user, host, password, options = {})
password ||= ''

unless options[:hash]
password = "PASSWORD('#{escape(password)}')"
password = "SELECT CONCAT('*', UPPER(SHA1(UNHEX(SHA1('#{escape(password)}'))))) AS PASSWORD"
end

sql = 'SET PASSWORD FOR %s = %s' % [
Expand Down Expand Up @@ -166,7 +173,7 @@ def revoke(user, host, object, options = {})

def revoke0(user, host, object, privs)
sql = 'REVOKE %s ON %s FROM %s' % [
privs.join(', '),
privs.join(', ').gsub('\'', '').strip,
quote_object(object),
quote_user(user, host),
]
Expand Down
4 changes: 2 additions & 2 deletions lib/gratan/grant_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ def parse_identified
end

def parse_main
md = /\AGRANT\s+(.+?)\s+ON\s+(.+?)\s+TO\s+'(.*)'@'(.+)'\z/.match(@stmt)
md = /\AGRANT\s+(.+?)\s+ON\s+(.+?)\s+TO\s+'(.*)'@'(.+)'\z/.match(@stmt.gsub('`', '\''))
privs, object, user, host = md.captures
@parsed[:privs] = parse_privs(privs.strip)
@parsed[:object] = object.gsub('`', '').strip
@parsed[:object] = object.gsub('\'', '').strip
@parsed[:user] = user
@parsed[:host] = host
end
Expand Down
12 changes: 6 additions & 6 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
end
end

def mysql57?
ENV['MYSQL57'] == '1'
def mysql80?
ENV['MYSQL80'] == '1'
end

MYSQL_PORT = mysql57? ? 14407 : 14406
MYSQL_PORT = mysql80? ? 3308 : 3307

def mysql
client = nil
Expand Down Expand Up @@ -127,7 +127,7 @@ def show_grants
end
end

if mysql57?
if mysql80?
grants.each do |grant|
end
end
Expand All @@ -148,7 +148,7 @@ def client(user_options = {})
logger: Logger.new('/dev/null'),
}

if mysql57?
if mysql80?
options.update(
override_sql_mode: true,
use_show_create_user: true,
Expand Down Expand Up @@ -189,7 +189,7 @@ def apply(cli = client)

class Array
def normalize
if mysql57?
if mysql80?
self.map do |i|
i.sub(/ IDENTIFIED BY PASSWORD '[^']+'/, '')
.sub(/ REQUIRE \w+\b/, '')
Expand Down