Skip to content

Commit

Permalink
Ignore double quotes in grants
Browse files Browse the repository at this point in the history
Also improve grant debuggability by printing them out
  • Loading branch information
petoju committed Jan 27, 2023
1 parent ce67394 commit 35b8ae0
Showing 1 changed file with 14 additions and 10 deletions.
24 changes: 14 additions & 10 deletions mysql/resource_grant.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"database/sql"
"fmt"
"github.com/hashicorp/go-version"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"log"
"regexp"
Expand All @@ -12,7 +13,6 @@ import (
"unicode"

"github.com/go-sql-driver/mysql"
"github.com/hashicorp/go-version"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

Expand Down Expand Up @@ -266,7 +266,7 @@ func CreateGrant(ctx context.Context, d *schema.ResourceData, meta interface{})
func ReadGrant(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
db, err := getDatabaseFromMeta(ctx, meta)
if err != nil {
return diag.FromErr(err)
return diag.Errorf("failed getting database from Meta: %v", err)
}

hasRoles, err := supportsRoles(ctx, meta)
Expand Down Expand Up @@ -536,29 +536,30 @@ func restoreGrant(user string, host string, grant *MySQLGrant) *schema.ResourceD
func showGrants(ctx context.Context, db *sql.DB, user, database, table string) ([]*MySQLGrant, error) {
allGrants, err := showUserGrants(ctx, db, user)
if err != nil {
return nil, err
return nil, fmt.Errorf("showGrants - getting all grants failed: %w", err)
}
grants := []*MySQLGrant{}
for _, grant := range allGrants {
if grant.Database == database && grant.Table == table {
grants = append(grants, grant)
}
}
return grants, err
return grants, nil
}

func showUserGrants(ctx context.Context, db *sql.DB, user string) ([]*MySQLGrant, error) {
grants := []*MySQLGrant{}

sqlStatement := fmt.Sprintf("SHOW GRANTS FOR %s", user)
log.Printf("[DEBUG] SQL: %s", sqlStatement)
rows, err := db.QueryContext(ctx, sqlStatement)

if isNonExistingGrant(err) {
return []*MySQLGrant{}, nil
}

if err != nil {
return nil, err
return nil, fmt.Errorf("showUserGrants - getting grants failed: %w", err)
}

defer rows.Close()
Expand All @@ -573,7 +574,7 @@ func showUserGrants(ctx context.Context, db *sql.DB, user string) ([]*MySQLGrant

err := rows.Scan(&rawGrant)
if err != nil {
return nil, err
return nil, fmt.Errorf("showUserGrants - reading row failed: %w", err)
}

if strings.HasPrefix(rawGrant, "REVOKE") {
Expand All @@ -593,12 +594,13 @@ func showUserGrants(ctx context.Context, db *sql.DB, user string) ([]*MySQLGrant
if normalizeUserHost(grantUserHost) != normalizeUserHost(user) {
// Percona returns also grants for % if we requested IP.
// Skip them as we don't want terraform to consider it.
log.Printf("[DEBUG] Skipping grant with host %v while we want %v", grantUserHost, user)
continue
}

grant := &MySQLGrant{
Database: strings.ReplaceAll(m[2], "`", ""),
Table: strings.Trim(m[3], "`"),
Database: strings.Trim(m[2], "`\""),
Table: strings.Trim(m[3], "`\""),
Privileges: privileges,
Grant: reGrant.MatchString(rawGrant),
}
Expand All @@ -613,7 +615,7 @@ func showUserGrants(ctx context.Context, db *sql.DB, user string) ([]*MySQLGrant
roles := make([]string, len(rolesStart))

for i, role := range rolesStart {
roles[i] = strings.Trim(role, "`@% ")
roles[i] = strings.Trim(role, "`@%\" ")
}

grant := &MySQLGrant{
Expand All @@ -627,6 +629,7 @@ func showUserGrants(ctx context.Context, db *sql.DB, user string) ([]*MySQLGrant
}
}

log.Printf("[DEBUG] Parsed grants are: %v", grants)
return grants, nil
}

Expand All @@ -636,7 +639,8 @@ func normalizeUserHost(userHost string) string {
}
withoutQuotes := strings.ReplaceAll(userHost, "'", "")
withoutBackticks := strings.ReplaceAll(withoutQuotes, "`", "")
return withoutBackticks
withoutDblQuotes := strings.ReplaceAll(withoutBackticks, "\"", "")
return withoutDblQuotes
}

func removeUselessPerms(grants []string) []string {
Expand Down

0 comments on commit 35b8ae0

Please sign in to comment.