Skip to content

Commit ccbc0c5

Browse files
add create user for db
1 parent 2719b44 commit ccbc0c5

File tree

4 files changed

+220
-105
lines changed

4 files changed

+220
-105
lines changed

pkg/connector/database.go

Lines changed: 20 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -24,80 +24,6 @@ type databaseSyncer struct {
2424
client *mssqldb.Client
2525
}
2626

27-
var databasePermissions = map[string]string{
28-
"AADS": "Alter Any Database Event Session",
29-
"AAMK": "Alter Any Mask",
30-
"AEDS": "Alter Any External Data Source",
31-
"AEFF": "Alter Any External File Format",
32-
"AL": "Alter",
33-
"ALAK": "Alter Any Asymmetric Key",
34-
"ALAR": "Alter Any Application Role",
35-
"ALAS": "Alter Any Assembly",
36-
"ALCF": "Alter Any Certificate",
37-
"ALDS": "Alter Any Dataspace",
38-
"ALED": "Alter Any Database Event Notification",
39-
"ALFT": "Alter Any Fulltext Catalog",
40-
"ALMT": "Alter Any Message Type",
41-
"ALRL": "Alter Any Role",
42-
"ALRT": "Alter Any Route",
43-
"ALSB": "Alter Any Remote Service Binding",
44-
"ALSC": "Alter Any Contract",
45-
"ALSK": "Alter Any Symmetric Key",
46-
"ALSM": "Alter Any Schema",
47-
"ALSV": "Alter Any Service",
48-
"ALTG": "Alter Any Database DDL Trigger",
49-
"ALUS": "Alter Any User",
50-
"AUTH": "Authenticate",
51-
"BADB": "Backup Database",
52-
"BALO": "Backup Log",
53-
"CL": "Control",
54-
"CO": "Connect",
55-
"CORP": "Connect Replication",
56-
"CP": "Checkpoint",
57-
"CRAG": "Create Aggregate",
58-
"CRAK": "Create Asymmetric Key",
59-
"CRAS": "Create Certificate",
60-
"CRDB": "Create Fatabase",
61-
"CRDF": "Create Default",
62-
"CRED": "Create Database DDL Event Notification",
63-
"CRFN": "Create Function",
64-
"CRFT": "Create Fulltext Catalog",
65-
"CRMT": "Create Message Type",
66-
"CRPR": "Create Procedure",
67-
"CRQU": "Create Queue",
68-
"CRRL": "Create Role",
69-
"CRRT": "Create Route",
70-
"CRRU": "Create Rule",
71-
"CRSB": "Create Remote Service Binding",
72-
"CRSC": "Create contract",
73-
"CRSK": "Create symmetric key",
74-
"CRSM": "Create Schema",
75-
"CRSN": "Create Synonym",
76-
"CRSO": "Create Sequence",
77-
"CRSV": "Create Service",
78-
"CRTB": "Create Table",
79-
"CRTY": "Create Type",
80-
"CRVW": "Create View",
81-
"CRXS": "Create XML Schema Collection",
82-
"DL": "Delete",
83-
"DABO": "Administer Database Bulk Operations",
84-
"EAES": "Execute Any External Script",
85-
"EX": "Execute",
86-
"IN": "Insert",
87-
"RC": "Receive Object",
88-
"RF": "References",
89-
"SL": "Select",
90-
"SPLN": "Showplan",
91-
"SUQN": "Subscribe Query Notifications",
92-
"TO": "Take Ownership",
93-
"UP": "Update",
94-
"VW": "View Definition",
95-
"VWCK": "View Any Column Encryption Key Definition",
96-
"VWCM": "View Any Column Master Key Definition",
97-
"VWCT": "View Change Tracking",
98-
"VWDS": "View Database State Database",
99-
}
100-
10127
func (d *databaseSyncer) ResourceType(ctx context.Context) *v2.ResourceType {
10228
return d.resourceType
10329
}
@@ -137,7 +63,7 @@ func (d *databaseSyncer) List(ctx context.Context, parentResourceID *v2.Resource
13763
func (d *databaseSyncer) Entitlements(ctx context.Context, resource *v2.Resource, pToken *pagination.Token) ([]*v2.Entitlement, string, annotations.Annotations, error) {
13864
var ret []*v2.Entitlement
13965

140-
for key, name := range databasePermissions {
66+
for key, name := range mssqldb.DatabasePermissions {
14167
grantSlug := fmt.Sprintf("%s (With Grant)", name)
14268
ret = append(ret,
14369
&v2.Entitlement{
@@ -184,7 +110,7 @@ func (d *databaseSyncer) Grants(ctx context.Context, resource *v2.Resource, pTok
184110
perms := strings.Split(p.Permissions, ",")
185111
for _, perm := range perms {
186112
perm = strings.TrimSpace(perm)
187-
if _, ok := databasePermissions[perm]; ok {
113+
if _, ok := mssqldb.DatabasePermissions[perm]; ok {
188114
rt, err := resourceTypeFromDatabasePrincipal(p.PrincipalType)
189115
if err != nil {
190116
l.Error("unexpected principal type", zap.String("principal_type", p.PrincipalType))
@@ -235,6 +161,8 @@ func (d *databaseSyncer) Grants(ctx context.Context, resource *v2.Resource, pTok
235161
}
236162

237163
func (d *databaseSyncer) Grant(ctx context.Context, resource *v2.Resource, entitlement *v2.Entitlement) ([]*v2.Grant, annotations.Annotations, error) {
164+
l := ctxzap.Extract(ctx)
165+
238166
if resource.Id.ResourceType != resourceTypeUser.Id {
239167
return nil, nil, fmt.Errorf("resource type %s is not supported for granting", resource.Id.ResourceType)
240168
}
@@ -260,11 +188,25 @@ func (d *databaseSyncer) Grant(ctx context.Context, resource *v2.Resource, entit
260188
return nil, nil, err
261189
}
262190

263-
user, err := d.client.GetUser(ctx, resource.Id.Resource)
191+
user, err := d.client.GetUserPrincipal(ctx, resource.Id.Resource)
264192
if err != nil {
265193
return nil, nil, err
266194
}
267195

196+
dbUser, err := d.client.GetUserFromDb(ctx, database.Name, resource.Id.Resource)
197+
if err != nil {
198+
return nil, nil, err
199+
}
200+
201+
if dbUser == nil {
202+
l.Info("user not found in database, creating user for principal", zap.String("user", resource.Id.Resource))
203+
204+
err = d.client.CreateDatabaseUserForPrincipal(ctx, database.Name, user.Name)
205+
if err != nil {
206+
return nil, nil, err
207+
}
208+
}
209+
268210
err = d.client.GrantPermissionOnDatabase(ctx, permission, database.Name, user.Name)
269211
if err != nil {
270212
return nil, nil, err
@@ -304,7 +246,7 @@ func (d *databaseSyncer) Revoke(ctx context.Context, grant *v2.Grant) (annotatio
304246
return nil, err
305247
}
306248

307-
user, err := d.client.GetUser(ctx, grant.Principal.Id.Resource)
249+
user, err := d.client.GetUserPrincipal(ctx, grant.Principal.Id.Resource)
308250
if err != nil {
309251
return nil, err
310252
}

pkg/mssqldb/allowed.go

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
package mssqldb
2+
3+
var DatabasePermissions = map[string]string{
4+
"AADS": "Alter Any Database Event Session",
5+
"AAMK": "Alter Any Mask",
6+
"AEDS": "Alter Any External Data Source",
7+
"AEFF": "Alter Any External File Format",
8+
"AL": "Alter",
9+
"ALAK": "Alter Any Asymmetric Key",
10+
"ALAR": "Alter Any Application Role",
11+
"ALAS": "Alter Any Assembly",
12+
"ALCF": "Alter Any Certificate",
13+
"ALDS": "Alter Any Dataspace",
14+
"ALED": "Alter Any Database Event Notification",
15+
"ALFT": "Alter Any Fulltext Catalog",
16+
"ALMT": "Alter Any Message Type",
17+
"ALRL": "Alter Any Role",
18+
"ALRT": "Alter Any Route",
19+
"ALSB": "Alter Any Remote Service Binding",
20+
"ALSC": "Alter Any Contract",
21+
"ALSK": "Alter Any Symmetric Key",
22+
"ALSM": "Alter Any Schema",
23+
"ALSV": "Alter Any Service",
24+
"ALTG": "Alter Any Database DDL Trigger",
25+
"ALUS": "Alter Any User",
26+
"AUTH": "Authenticate",
27+
"BADB": "Backup Database",
28+
"BALO": "Backup Log",
29+
"CL": "Control",
30+
"CO": "Connect",
31+
"CORP": "Connect Replication",
32+
"CP": "Checkpoint",
33+
"CRAG": "Create Aggregate",
34+
"CRAK": "Create Asymmetric Key",
35+
"CRAS": "Create Certificate",
36+
"CRDB": "Create Fatabase",
37+
"CRDF": "Create Default",
38+
"CRED": "Create Database DDL Event Notification",
39+
"CRFN": "Create Function",
40+
"CRFT": "Create Fulltext Catalog",
41+
"CRMT": "Create Message Type",
42+
"CRPR": "Create Procedure",
43+
"CRQU": "Create Queue",
44+
"CRRL": "Create Role",
45+
"CRRT": "Create Route",
46+
"CRRU": "Create Rule",
47+
"CRSB": "Create Remote Service Binding",
48+
"CRSC": "Create contract",
49+
"CRSK": "Create symmetric key",
50+
"CRSM": "Create Schema",
51+
"CRSN": "Create Synonym",
52+
"CRSO": "Create Sequence",
53+
"CRSV": "Create Service",
54+
"CRTB": "Create Table",
55+
"CRTY": "Create Type",
56+
"CRVW": "Create View",
57+
"CRXS": "Create XML Schema Collection",
58+
"DL": "Delete",
59+
"DABO": "Administer Database Bulk Operations",
60+
"EAES": "Execute Any External Script",
61+
"EX": "Execute",
62+
"IN": "Insert",
63+
"RC": "Receive Object",
64+
"RF": "References",
65+
"SL": "Select",
66+
"SPLN": "Showplan",
67+
"SUQN": "Subscribe Query Notifications",
68+
"TO": "Take Ownership",
69+
"UP": "Update",
70+
"VW": "View Definition",
71+
"VWCK": "View Any Column Encryption Key Definition",
72+
"VWCM": "View Any Column Master Key Definition",
73+
"VWCT": "View Change Tracking",
74+
"VWDS": "View Database State Database",
75+
}

pkg/mssqldb/databases.go

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package mssqldb
22

33
import (
44
"context"
5+
"fmt"
56
"strconv"
67
"strings"
78

@@ -98,9 +99,23 @@ func (c *Client) GrantPermissionOnDatabase(ctx context.Context, permission, db,
9899
zap.String("user", user),
99100
)
100101

101-
command := `
102-
GRANT @p1 ON DATABASE::@p2 TO @p3;
103-
`
102+
fullPermission, ok := DatabasePermissions[strings.ToUpper(permission)]
103+
if !ok {
104+
return fmt.Errorf("permission %s is not allowed", permission)
105+
}
106+
107+
if strings.ContainsAny(db, "[]\"';") || strings.ContainsAny(user, "[]\"';") {
108+
return fmt.Errorf("invalid characters in dbName or user")
109+
}
110+
111+
command := fmt.Sprintf(
112+
"GRANT %s ON DATABASE::[%s] TO [%s];",
113+
fullPermission,
114+
db,
115+
user,
116+
)
117+
118+
l.Debug("SQL QUERY", zap.String("q", command))
104119

105120
_, err := c.db.ExecContext(ctx, command, permission, db, user)
106121
if err != nil {
@@ -113,17 +128,29 @@ GRANT @p1 ON DATABASE::@p2 TO @p3;
113128
func (c *Client) RevokePermissionOnDatabase(ctx context.Context, permission, db, user string) error {
114129
l := ctxzap.Extract(ctx)
115130
l.Debug(
116-
"granting permission on database",
131+
"revoking permission on database",
117132
zap.String("permission", permission),
118133
zap.String("db", db),
119134
zap.String("user", user),
120135
)
121136

122-
command := `
123-
REVOKE @p1 ON DATABASE::@p2 TO @p3;
124-
`
137+
fullPermission, ok := DatabasePermissions[strings.ToUpper(permission)]
138+
if !ok {
139+
return fmt.Errorf("permission %s is not allowed", permission)
140+
}
125141

126-
_, err := c.db.ExecContext(ctx, command, permission, db, user)
142+
if strings.ContainsAny(db, "[]\"';") || strings.ContainsAny(user, "[]\"';") {
143+
return fmt.Errorf("invalid characters in dbName or user")
144+
}
145+
146+
command := fmt.Sprintf(
147+
"GRANT %s ON DATABASE::[%s] TO [%s];",
148+
fullPermission,
149+
db,
150+
user,
151+
)
152+
153+
_, err := c.db.ExecContext(ctx, command, fullPermission, db, user)
127154
if err != nil {
128155
return err
129156
}

0 commit comments

Comments
 (0)