-
Notifications
You must be signed in to change notification settings - Fork 7
/
privilege_default_privilege.go
168 lines (142 loc) · 4.95 KB
/
privilege_default_privilege.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
package materialize
import (
"database/sql"
"fmt"
"strings"
"github.com/jmoiron/sqlx"
)
type DefaultPrivilegeBuilder struct {
ddl Builder
granteeRole MaterializeRole
targetRole MaterializeRole
objectType string
privilege string
schemaName string
databaseName string
}
func NewDefaultPrivilegeBuilder(conn *sqlx.DB, objectType, grantee, target, privilege string) *DefaultPrivilegeBuilder {
return &DefaultPrivilegeBuilder{
ddl: Builder{conn, Privilege},
objectType: objectType,
privilege: privilege,
granteeRole: MaterializeRole{name: grantee},
targetRole: MaterializeRole{name: target},
}
}
func (b *DefaultPrivilegeBuilder) SchemaName(c string) *DefaultPrivilegeBuilder {
b.schemaName = c
return b
}
func (b *DefaultPrivilegeBuilder) DatabaseName(c string) *DefaultPrivilegeBuilder {
b.databaseName = c
return b
}
func (b *DefaultPrivilegeBuilder) baseQuery(action string) error {
q := strings.Builder{}
q.WriteString(`ALTER DEFAULT PRIVILEGES`)
// role
if b.targetRole.name == "PUBLIC" {
q.WriteString(" FOR ALL ROLES")
} else {
q.WriteString(fmt.Sprintf(` FOR ROLE %s`, b.targetRole.QualifiedName()))
}
// object location
if b.schemaName != "" && b.databaseName != "" {
q.WriteString(fmt.Sprintf(` IN SCHEMA "%[1]s"."%[2]s"`, b.databaseName, b.schemaName))
} else if b.databaseName != "" {
q.WriteString(fmt.Sprintf(` IN DATABASE "%s"`, b.databaseName))
} else {
}
var grantDirection string
if action == "GRANT" {
grantDirection = "TO"
} else {
grantDirection = "FROM"
}
q.WriteString(fmt.Sprintf(` %[1]s %[2]s ON %[3]sS %[4]s`, action, b.privilege, b.objectType, grantDirection))
if b.granteeRole.name == "PUBLIC" {
q.WriteString(" PUBLIC")
} else {
q.WriteString(fmt.Sprintf(` %[1]s`, b.granteeRole.QualifiedName()))
}
return b.ddl.exec(q.String())
}
func (b *DefaultPrivilegeBuilder) Grant() error {
return b.baseQuery("GRANT")
}
func (b *DefaultPrivilegeBuilder) Revoke() error {
return b.baseQuery("REVOKE")
}
func (b *DefaultPrivilegeBuilder) GrantKey(region, objectType, granteeId, targetId, databaseId, schemaId, privilege string) string {
return fmt.Sprintf(`%[1]s:GRANT DEFAULT|%[2]s|%[3]s|%[4]s|%[5]s|%[6]s|%[7]s`, region, objectType, granteeId, targetId, databaseId, schemaId, privilege)
}
type DefaultPrivilegeParams struct {
ObjectType sql.NullString `db:"object_type"`
GranteeId sql.NullString `db:"grantee_id"`
GranteeName sql.NullString `db:"grantee_name"`
TargetId sql.NullString `db:"target_id"`
TargetName sql.NullString `db:"target_name"`
DatabaseId sql.NullString `db:"database_id"`
SchemaId sql.NullString `db:"schema_id"`
Privileges sql.NullString `db:"privileges"`
}
var defaultPrivilegeQuery = NewBaseQuery(`
SELECT
mz_default_privileges.object_type,
mz_default_privileges.grantee AS grantee_id,
(CASE WHEN mz_default_privileges.grantee = 'p' THEN 'PUBLIC' ELSE grantee.name END) AS grantee_name,
mz_default_privileges.role_id AS target_id,
(CASE WHEN mz_default_privileges.role_id = 'p' THEN 'PUBLIC' ELSE target.name END) AS target_name,
mz_default_privileges.database_id AS database_id,
mz_default_privileges.schema_id AS schema_id,
mz_default_privileges.privileges
FROM mz_default_privileges
LEFT JOIN mz_roles AS grantee
ON mz_default_privileges.grantee = grantee.id
LEFT JOIN mz_roles AS target
ON mz_default_privileges.role_id = target.id
LEFT JOIN mz_schemas
ON mz_default_privileges.schema_id = mz_schemas.id
LEFT JOIN mz_databases
ON mz_default_privileges.database_id = mz_databases.id`)
func ScanDefaultPrivilege(conn *sqlx.DB, objectType, granteeId, targetRoleId, databaseId, schemaId string) ([]DefaultPrivilegeParams, error) {
p := map[string]string{
"mz_default_privileges.object_type": strings.ToLower(objectType),
"mz_default_privileges.grantee": granteeId,
"mz_default_privileges.role_id": targetRoleId,
}
if databaseId != "" {
p["mz_default_privileges.database_id"] = databaseId
}
if schemaId != "" {
p["mz_default_privileges.schema_id"] = schemaId
}
q := defaultPrivilegeQuery.QueryPredicate(p)
var c []DefaultPrivilegeParams
if err := conn.Select(&c, q); err != nil {
return c, err
}
return c, nil
}
// Converts a list of DefaultPrivilegeParamss into a map
// list of DefaultPrivilegeParamss would become
// map[string][]string
//
// {
// "TYPE|p|s1||": {"USAGE", "INSERT"},
// "CLUSTER|s2|s1|u3|u8": {"USAGE"},
// }
func MapDefaultGrantPrivileges(privileges []DefaultPrivilegeParams) (map[string][]string, error) {
mapping := make(map[string][]string)
for _, p := range privileges {
// Construct compund grant key
key := p.ObjectType.String + "|" + p.GranteeId.String + "|" + p.TargetId.String + "|" + p.DatabaseId.String + "|" + p.SchemaId.String
parsedPrivileges := []string{}
for _, rp := range strings.Split(p.Privileges.String, "") {
pName, _ := PrivilegeName(rp)
parsedPrivileges = append(parsedPrivileges, pName)
}
mapping[key] = parsedPrivileges
}
return mapping, nil
}