Refactor of the grant function
This commit is contained in:
parent
44b8e232d1
commit
9bd72b30b2
@ -23,6 +23,35 @@ import (
|
|||||||
|
|
||||||
const startSlavePostWaitMilliseconds = 500 * time.Millisecond
|
const startSlavePostWaitMilliseconds = 500 * time.Millisecond
|
||||||
|
|
||||||
|
var grantOnRegexp = regexp.MustCompile(" ON `(.*?)`\\.\\*")
|
||||||
|
|
||||||
|
func grantMatch(grant string, databaseName string) bool {
|
||||||
|
matches := grantOnRegexp.FindStringSubmatch(grant)
|
||||||
|
if matches == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
mysqlPattern := matches[1]
|
||||||
|
regexPattern := "^"
|
||||||
|
escape := false
|
||||||
|
for _, c := range mysqlPattern {
|
||||||
|
if escape {
|
||||||
|
regexPattern += regexp.QuoteMeta(string(c))
|
||||||
|
escape = false
|
||||||
|
} else if c == '%' {
|
||||||
|
regexPattern += ".*"
|
||||||
|
} else if c == '_' {
|
||||||
|
regexPattern += "."
|
||||||
|
} else if c == '\\' {
|
||||||
|
escape = true
|
||||||
|
} else {
|
||||||
|
regexPattern += regexp.QuoteMeta(string(c))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
regexPattern += "$"
|
||||||
|
match, _ := regexp.MatchString(regexPattern, databaseName)
|
||||||
|
return match
|
||||||
|
}
|
||||||
|
|
||||||
// Inspector reads data from the read-MySQL-server (typically a replica, but can be the master)
|
// Inspector reads data from the read-MySQL-server (typically a replica, but can be the master)
|
||||||
// It is used for gaining initial status and structure, and later also follow up on progress and changelog
|
// It is used for gaining initial status and structure, and later also follow up on progress and changelog
|
||||||
type Inspector struct {
|
type Inspector struct {
|
||||||
@ -31,7 +60,6 @@ type Inspector struct {
|
|||||||
informationSchemaDb *gosql.DB
|
informationSchemaDb *gosql.DB
|
||||||
migrationContext *base.MigrationContext
|
migrationContext *base.MigrationContext
|
||||||
name string
|
name string
|
||||||
grantOnRe *regexp.Regexp
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewInspector(migrationContext *base.MigrationContext) *Inspector {
|
func NewInspector(migrationContext *base.MigrationContext) *Inspector {
|
||||||
@ -39,7 +67,6 @@ func NewInspector(migrationContext *base.MigrationContext) *Inspector {
|
|||||||
connectionConfig: migrationContext.InspectorConnectionConfig,
|
connectionConfig: migrationContext.InspectorConnectionConfig,
|
||||||
migrationContext: migrationContext,
|
migrationContext: migrationContext,
|
||||||
name: "inspector",
|
name: "inspector",
|
||||||
grantOnRe: regexp.MustCompile(" ON `(.*?)`\\.\\*"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,33 +308,7 @@ func (this *Inspector) grantContainsAll(grant string, substrings ...string) bool
|
|||||||
if !base.StringContainsAll(grant, substrings...) {
|
if !base.StringContainsAll(grant, substrings...) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if strings.Contains(grant, ` ON *.*`) {
|
return strings.Contains(grant, ` ON *.*`) || grantMatch(grant, this.migrationContext.DatabaseName)
|
||||||
return true
|
|
||||||
}
|
|
||||||
matches := this.grantOnRe.FindStringSubmatch(grant)
|
|
||||||
if matches == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
mysqlPattern := matches[1]
|
|
||||||
regexPattern := "^"
|
|
||||||
escape := false
|
|
||||||
for _, c := range mysqlPattern {
|
|
||||||
if escape {
|
|
||||||
regexPattern += regexp.QuoteMeta(string(c))
|
|
||||||
escape = false
|
|
||||||
} else if c == '%' {
|
|
||||||
regexPattern += ".*"
|
|
||||||
} else if c == '_' {
|
|
||||||
regexPattern += "."
|
|
||||||
} else if c == '\\' {
|
|
||||||
escape = true
|
|
||||||
} else {
|
|
||||||
regexPattern += regexp.QuoteMeta(string(c))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
regexPattern += "$"
|
|
||||||
match, _ := regexp.MatchString(regexPattern, this.migrationContext.DatabaseName)
|
|
||||||
return match
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// restartReplication is required so that we are _certain_ the binlog format and
|
// restartReplication is required so that we are _certain_ the binlog format and
|
||||||
|
31
go/logic/inspect_test.go
Normal file
31
go/logic/inspect_test.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2022 GitHub Inc.
|
||||||
|
See https://github.com/github/gh-ost/blob/master/LICENSE
|
||||||
|
*/
|
||||||
|
|
||||||
|
package logic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/openark/golib/log"
|
||||||
|
test "github.com/openark/golib/tests"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
log.SetLevel(log.ERROR)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGrantMatch(t *testing.T) {
|
||||||
|
databaseName := `my_database%name`
|
||||||
|
|
||||||
|
test.S(t).ExpectFalse(grantMatch("GRANT SELECT ON *.* TO 'user'@'%'", databaseName))
|
||||||
|
test.S(t).ExpectFalse(grantMatch("GRANT SELECT ON `other\\_database\\%name`.* TO 'user'@'%'", databaseName))
|
||||||
|
test.S(t).ExpectTrue(grantMatch("GRANT SELECT ON `my\\_database\\%name`.* TO 'user'@'%'", databaseName))
|
||||||
|
test.S(t).ExpectTrue(grantMatch("GRANT SELECT ON `my_database_name`.* TO 'user'@'%'", databaseName))
|
||||||
|
test.S(t).ExpectTrue(grantMatch("GRANT SELECT ON `my\\_database\\%%`.* TO 'user'@'%'", databaseName))
|
||||||
|
test.S(t).ExpectFalse(grantMatch("GRANT SELECT ON `database\\%%`.* TO 'user'@'%'", databaseName))
|
||||||
|
test.S(t).ExpectTrue(grantMatch("GRANT SELECT ON `my\\_database\\%____`.* TO 'user'@'%'", databaseName))
|
||||||
|
test.S(t).ExpectFalse(grantMatch("GRANT SELECT ON `my\\_database\\%_`.* TO 'user'@'%'", databaseName))
|
||||||
|
test.S(t).ExpectTrue(grantMatch("GRANT SELECT ON `%database%`.* TO 'user'@'%'", databaseName))
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user