Skip to content

Commit bd11372

Browse files
authored
Merge pull request #136 from Datameer-Inc/turtle/ELT-16035
Allow writer user to create tables in schema
2 parents 9c05343 + 9383b14 commit bd11372

File tree

5 files changed

+49
-18
lines changed

5 files changed

+49
-18
lines changed

pkg/controller/postgres/postgres_controller.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,12 +220,20 @@ func (r *ReconcilePostgres) Reconcile(request reconcile.Request) (_ reconcile.Re
220220
}
221221

222222
// Set privileges on schema
223-
err = r.pg.SetSchemaPrivileges(database, owner, reader, schema, readerPrivs, reqLogger)
223+
schemaPrivilegesReader := postgres.PostgresSchemaPrivileges{database, owner, reader, schema, readerPrivs, false}
224+
err = r.pg.SetSchemaPrivileges(schemaPrivilegesReader, reqLogger)
224225
if err != nil {
225226
reqLogger.Error(err, fmt.Sprintf("Could not give %s permissions \"%s\"", reader, readerPrivs))
226227
continue
227228
}
228-
err = r.pg.SetSchemaPrivileges(database, owner, writer, schema, writerPrivs, reqLogger)
229+
schemaPrivilegesWriter := postgres.PostgresSchemaPrivileges{database, owner, writer, schema, readerPrivs, true}
230+
err = r.pg.SetSchemaPrivileges(schemaPrivilegesWriter, reqLogger)
231+
if err != nil {
232+
reqLogger.Error(err, fmt.Sprintf("Could not give %s permissions \"%s\"", writer, writerPrivs))
233+
continue
234+
}
235+
schemaPrivilegesOwner := postgres.PostgresSchemaPrivileges{database, owner, owner, schema, readerPrivs, true}
236+
err = r.pg.SetSchemaPrivileges(schemaPrivilegesOwner, reqLogger)
229237
if err != nil {
230238
reqLogger.Error(err, fmt.Sprintf("Could not give %s permissions \"%s\"", writer, writerPrivs))
231239
continue

pkg/controller/postgres/postgres_controller_test.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -682,10 +682,10 @@ var _ = Describe("ReconcilePostgres", func() {
682682
// Expected method calls
683683
// customers schema
684684
pg.EXPECT().CreateSchema(name, name+"-group", "customers", gomock.Any()).Return(nil).Times(1)
685-
pg.EXPECT().SetSchemaPrivileges(name, name+"-group", gomock.Any(), "customers", gomock.Any(), gomock.Any()).Return(nil).Times(2)
685+
pg.EXPECT().SetSchemaPrivileges(name, name+"-group", gomock.Any(), "customers", gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(3)
686686
// stores schema
687687
pg.EXPECT().CreateSchema(name, name+"-group", "stores", gomock.Any()).Return(nil).Times(1)
688-
pg.EXPECT().SetSchemaPrivileges(name, name+"-group", gomock.Any(), "stores", gomock.Any(), gomock.Any()).Return(nil).Times(2)
688+
pg.EXPECT().SetSchemaPrivileges(name, name+"-group", gomock.Any(), "stores", gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(3)
689689
})
690690

691691
It("should update status", func() {
@@ -707,10 +707,12 @@ var _ = Describe("ReconcilePostgres", func() {
707707
// Expected method calls
708708
// customers schema errors
709709
pg.EXPECT().CreateSchema(name, name+"-group", "customers", gomock.Any()).Return(fmt.Errorf("Could not create schema")).Times(1)
710-
pg.EXPECT().SetSchemaPrivileges(name, name+"-group", gomock.Any(), "customers", gomock.Any(), gomock.Any()).Return(nil).Times(0)
710+
pg.EXPECT().SetSchemaPrivileges(name, name+"-group", gomock.Any(), "customers", gomock.Any(), gomock.Any() ,gomock.Any()).Return(nil).Times(0)
711711
// stores schema
712712
pg.EXPECT().CreateSchema(name, name+"-group", "stores", gomock.Any()).Return(nil).Times(1)
713-
pg.EXPECT().SetSchemaPrivileges(name, name+"-group", gomock.Any(), "stores", gomock.Any(), gomock.Any()).Return(nil).Times(2)
713+
pg.EXPECT().SetSchemaPrivileges(name, name+"-group", name+"-reader", "stores", gomock.Any(), false, gomock.Any()).Return(nil).Times(1)
714+
pg.EXPECT().SetSchemaPrivileges(name, name+"-group", name+"-writer", "stores", gomock.Any(), true, gomock.Any()).Return(nil).Times(1)
715+
pg.EXPECT().SetSchemaPrivileges(name, name+"-group", name+"-group", "stores", gomock.Any(), true, gomock.Any()).Return(nil).Times(1)
714716
})
715717

716718
It("should update status", func() {
@@ -751,7 +753,7 @@ var _ = Describe("ReconcilePostgres", func() {
751753
// Expected method calls
752754
// customers schema
753755
pg.EXPECT().CreateSchema(name, name+"-group", "customers", gomock.Any()).Return(nil).Times(1)
754-
pg.EXPECT().SetSchemaPrivileges(name, name+"-group", gomock.Any(), "customers", gomock.Any(), gomock.Any()).Return(nil).Times(2)
756+
pg.EXPECT().SetSchemaPrivileges(name, name+"-group", gomock.Any(), "customers", gomock.Any(), gomock.Any(), gomock.Any()).Return(nil).Times(3)
755757
// stores schema already exists
756758
pg.EXPECT().CreateSchema(name, name+"-group", "stores", gomock.Any()).Times(0)
757759
// Call reconcile

pkg/postgres/database.go

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const (
1414
ALTER_DB_OWNER = `ALTER DATABASE "%s" OWNER TO "%s"`
1515
DROP_DATABASE = `DROP DATABASE "%s"`
1616
GRANT_USAGE_SCHEMA = `GRANT USAGE ON SCHEMA "%s" TO "%s"`
17+
GRANT_CREATE_TABLE = `GRANT CREATE ON SCHEMA "%s" TO "%s"`
1718
GRANT_ALL_TABLES = `GRANT %s ON ALL TABLES IN SCHEMA "%s" TO "%s"`
1819
DEFAULT_PRIVS_SCHEMA = `ALTER DEFAULT PRIVILEGES FOR ROLE "%s" IN SCHEMA "%s" GRANT %s ON TABLES TO "%s"`
1920
REVOKE_CONNECT = `REVOKE CONNECT ON DATABASE "%s" FROM public`
@@ -94,29 +95,38 @@ func (c *pg) CreateExtension(db, extension string, logger logr.Logger) error {
9495
return nil
9596
}
9697

97-
func (c *pg) SetSchemaPrivileges(db, creator, role, schema, privs string, logger logr.Logger) error {
98-
tmpDb, err := GetConnection(c.user, c.pass, c.host, db, c.args, logger)
98+
func (c *pg) SetSchemaPrivileges(schemaPrivileges PostgresSchemaPrivileges, logger logr.Logger) error {
99+
tmpDb, err := GetConnection(c.user, c.pass, c.host, schemaPrivileges.DB, c.args, logger)
99100
if err != nil {
100101
return err
101102
}
102103
defer tmpDb.Close()
103104

104105
// Grant role usage on schema
105-
_, err = tmpDb.Exec(fmt.Sprintf(GRANT_USAGE_SCHEMA, schema, role))
106+
_, err = tmpDb.Exec(fmt.Sprintf(GRANT_USAGE_SCHEMA, schemaPrivileges.Schema, schemaPrivileges.Role))
106107
if err != nil {
107108
return err
108109
}
109110

110111
// Grant role privs on existing tables in schema
111-
_, err = tmpDb.Exec(fmt.Sprintf(GRANT_ALL_TABLES, privs, schema, role))
112+
_, err = tmpDb.Exec(fmt.Sprintf(GRANT_ALL_TABLES, schemaPrivileges.Privs, schemaPrivileges.Schema, schemaPrivileges.Role))
112113
if err != nil {
113114
return err
114115
}
115116

116117
// Grant role privs on future tables in schema
117-
_, err = tmpDb.Exec(fmt.Sprintf(DEFAULT_PRIVS_SCHEMA, creator, schema, privs, role))
118+
_, err = tmpDb.Exec(fmt.Sprintf(DEFAULT_PRIVS_SCHEMA, schemaPrivileges.Creator, schemaPrivileges.Schema, schemaPrivileges.Privs, schemaPrivileges.Role))
118119
if err != nil {
119120
return err
120121
}
122+
123+
// Grant role usage on schema if createSchema
124+
if schemaPrivileges.CreateSchema {
125+
_, err = tmpDb.Exec(fmt.Sprintf(GRANT_CREATE_TABLE, schemaPrivileges.Schema, schemaPrivileges.Role))
126+
if err != nil {
127+
return err
128+
}
129+
}
130+
121131
return nil
122132
}

pkg/postgres/mock/postgres.go

Lines changed: 7 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/postgres/postgres.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ type PG interface {
1616
CreateUserRole(role, password string) (string, error)
1717
UpdatePassword(role, password string) error
1818
GrantRole(role, grantee string) error
19-
SetSchemaPrivileges(db, creator, role, schema, privs string, logger logr.Logger) error
19+
SetSchemaPrivileges(schemaPrivileges PostgresSchemaPrivileges, logger logr.Logger) error
2020
RevokeRole(role, revoked string) error
2121
AlterDefaultLoginRole(role, setRole string) error
2222
DropDatabase(db string, logger logr.Logger) error
@@ -35,6 +35,15 @@ type pg struct {
3535
default_database string
3636
}
3737

38+
type PostgresSchemaPrivileges struct {
39+
DB string
40+
Creator string
41+
Role string
42+
Schema string
43+
Privs string
44+
CreateSchema bool
45+
}
46+
3847
func NewPG(host, user, password, uri_args, default_database, cloud_type string, logger logr.Logger) (PG, error) {
3948
db, err := GetConnection(user, password, host, default_database, uri_args, logger)
4049
if err != nil {

0 commit comments

Comments
 (0)