Skip to content

Commit

Permalink
fix: correctly set GRANT OPTION privilege (#149)
Browse files Browse the repository at this point in the history
* fix: correctly set GRANT OPTION privilege

Signed-off-by: Duologic <[email protected]>

* chore: introduce createRevokeQuery function

Signed-off-by: Javier Palomo <[email protected]>

* fix: use createRevokeQuery in Delete

Signed-off-by: Javier Palomo <[email protected]>

* fix: dont split user and host

Signed-off-by: Javier Palomo <[email protected]>

* fix: unnecessary type conversion in getPrivilegesString

Signed-off-by: Javier Palomo <[email protected]>

* fix(createRevokeQuery): use right MySQL syntax

Signed-off-by: Javier Palomo <[email protected]>

---------

Signed-off-by: Duologic <[email protected]>
Signed-off-by: Javier Palomo <[email protected]>
Co-authored-by: Duologic <[email protected]>
Signed-off-by: Timotej Avsec <[email protected]>
  • Loading branch information
2 people authored and tavsec committed Sep 14, 2023
1 parent fe4b811 commit 716e2a8
Showing 1 changed file with 35 additions and 30 deletions.
65 changes: 35 additions & 30 deletions pkg/controller/mysql/grant/reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,7 @@ func (c *external) Create(ctx context.Context, mg resource.Managed) (managed.Ext
dbname := defaultIdentifier(cr.Spec.ForProvider.Database)
table := defaultIdentifier(cr.Spec.ForProvider.Table)

privileges := strings.Join(cr.Spec.ForProvider.Privileges.ToStringSlice(), ", ")
grantOption := hasGrantOption(cr)
privileges, grantOption := getPrivilegesString(cr.Spec.ForProvider.Privileges.ToStringSlice())
binlog := cr.Spec.ForProvider.BinLog
query := createGrantQuery(privileges, dbname, username, table, grantOption)

Expand All @@ -278,25 +277,16 @@ func (c *external) Update(ctx context.Context, mg resource.Managed) (managed.Ext
username := *cr.Spec.ForProvider.User
dbname := defaultIdentifier(cr.Spec.ForProvider.Database)
table := defaultIdentifier(cr.Spec.ForProvider.Table)

username, host := mysql.SplitUserHost(username)
binlog := cr.Spec.ForProvider.BinLog

observed := cr.Status.AtProvider.Privileges
desired := cr.Spec.ForProvider.Privileges.ToStringSlice()
toGrant, toRevoke := diffPermissions(desired, observed)
grantOption := hasGrantOption(cr)

if len(toRevoke) > 0 {
sort.Strings(toRevoke)
query := fmt.Sprintf("REVOKE %s ON %s.%s FROM %s@%s",
strings.Join(toRevoke, ", "),
dbname,
table,
mysql.QuoteValue(username),
mysql.QuoteValue(host),
)

privileges, grantOption := getPrivilegesString(toRevoke)
query := createRevokeQuery(privileges, dbname, username, table, grantOption)
if err := mysql.ExecWithBinlogAndFlush(ctx, c.db,
mysql.ExecQuery{
Query: query, ErrorValue: errRevokeGrant,
Expand All @@ -308,7 +298,8 @@ func (c *external) Update(ctx context.Context, mg resource.Managed) (managed.Ext

if len(toGrant) > 0 {
sort.Strings(toGrant)
query := createGrantQuery(strings.Join(toGrant, ", "), dbname, username, table, grantOption)
privileges, grantOption := getPrivilegesString(toGrant)
query := createGrantQuery(privileges, dbname, username, table, grantOption)
if err := mysql.ExecWithBinlogAndFlush(ctx, c.db,
mysql.ExecQuery{
Query: query, ErrorValue: errCreateGrant,
Expand All @@ -320,14 +311,36 @@ func (c *external) Update(ctx context.Context, mg resource.Managed) (managed.Ext
return managed.ExternalUpdate{}, nil
}

// hasGrantOption returns true if the privileges has a grant option item
func hasGrantOption(cr *v1alpha1.Grant) bool {
for _, p := range cr.Spec.ForProvider.Privileges {
if string(p) == "GRANT OPTION" {
return true
// getPrivilegesString returns a privileges string without grant option item and a grantOption boolean
func getPrivilegesString(privileges []string) (string, bool) {
privilegesWithoutGrantOption := []string{}
grantOption := false
for _, p := range privileges {
if p == "GRANT OPTION" {
grantOption = true
continue
}
privilegesWithoutGrantOption = append(privilegesWithoutGrantOption, p)
}
return false
out := strings.Join(privilegesWithoutGrantOption, ", ")
return out, grantOption
}

func createRevokeQuery(privileges, dbname, username string, table string, grantOption bool) string {
username, host := mysql.SplitUserHost(username)
result := fmt.Sprintf("REVOKE %s ON %s.%s FROM %s@%s",
privileges,
dbname,
table,
mysql.QuoteValue(username),
mysql.QuoteValue(host),
)

if grantOption {
result = fmt.Sprintf("%s WITH GRANT OPTION", result)
}

return result
}

func createGrantQuery(privileges, dbname, username string, table string, grantOption bool) string {
Expand Down Expand Up @@ -356,18 +369,10 @@ func (c *external) Delete(ctx context.Context, mg resource.Managed) error {
username := *cr.Spec.ForProvider.User
dbname := defaultIdentifier(cr.Spec.ForProvider.Database)
table := defaultIdentifier(cr.Spec.ForProvider.Table)

privileges := strings.Join(cr.Spec.ForProvider.Privileges.ToStringSlice(), ", ")
username, host := mysql.SplitUserHost(username)
binlog := cr.Spec.ForProvider.BinLog

query := fmt.Sprintf("REVOKE %s ON %s.%s FROM %s@%s",
privileges,
dbname,
table,
mysql.QuoteValue(username),
mysql.QuoteValue(host),
)
privileges, grantOption := getPrivilegesString(cr.Spec.ForProvider.Privileges.ToStringSlice())
query := createRevokeQuery(privileges, dbname, username, table, grantOption)

if err := mysql.ExecWithBinlogAndFlush(ctx, c.db, mysql.ExecQuery{Query: query, ErrorValue: errRevokeGrant}, mysql.ExecOptions{Binlog: binlog}); err != nil {
var myErr *mysqldriver.MySQLError
Expand Down

0 comments on commit 716e2a8

Please sign in to comment.