Skip to content

Commit

Permalink
Add tests for 'Grant access to schema for role' (#36)
Browse files Browse the repository at this point in the history
  • Loading branch information
stephanpelikan committed Sep 18, 2024
1 parent b6a0d32 commit 0bc68b8
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 3 deletions.
4 changes: 3 additions & 1 deletion src/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,9 @@ const jumpTable: JumpTable = {
const sql: string[] = []
// TODO: revoke old role-name if props.RoleName was removed or changed
if (props.RoleName) {
revokeRoleFromSchema(resourceId, props.RoleName).forEach((stmt) => sql.push(stmt))
revokeRoleFromSchema(oldResourceIdgit , props.RoleName).forEach((stmt) =>
sql.push(stmt)
)
}
sql.push(format("alter schema %I rename to %I", oldResourceId, resourceId))
if (props.RoleName) {
Expand Down
36 changes: 34 additions & 2 deletions test/handler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
databaseExists,
databaseOwnerIs,
rowCount,
roleGrantedForSchema,
} from "./util"
import { handler } from "../src/handler"

Expand Down Expand Up @@ -67,6 +68,7 @@ test("schema", async () => {
const create = createRequest("schema", oldSchemaName)
await handler(create)
expect(SecretsManagerClientMock).toHaveBeenCalledTimes(1)

const client = await newClient()
try {
expect(await schemaExists(client, oldSchemaName)).toEqual(true)
Expand All @@ -76,9 +78,39 @@ test("schema", async () => {
expect(await schemaExists(client, newSchemaName)).toEqual(true)

// CloudFormation will send a delete afterward, so test that too
const remove = deleteRequest("schema", oldSchemaName)
const remove = deleteRequest("schema", newSchemaName)
await handler(remove)
expect(await schemaExists(client, oldSchemaName)).toEqual(false)
expect(await schemaExists(client, newSchemaName)).toEqual(false)

// create role for testing
const roleName = "schematest"
const createRole = createRequest("role", roleName, {
PasswordArn: "arn:aws:secretsmanager:us-east-1:123456789:secret:dummy",
DatabaseName: "postgres",
})
await handler(createRole)

const createWithRole = createRequest("schema", oldSchemaName, {
RoleName: roleName,
})
await handler(createWithRole)
expect(await roleGrantedForSchema(client, oldSchemaName, roleName)).toEqual(true)
const updateWithRole = updateRequest("schema", oldSchemaName, newSchemaName, {
RoleName: roleName,
})
await handler(updateWithRole)
expect(await roleGrantedForSchema(client, oldSchemaName, roleName)).toEqual(false)
expect(await roleGrantedForSchema(client, newSchemaName, roleName)).toEqual(true)
const removeWithRole = deleteRequest("schema", newSchemaName, {
RoleName: roleName,
})
await handler(removeWithRole)
expect(await roleGrantedForSchema(client, newSchemaName, roleName)).toEqual(false)

const removeRole = deleteRequest("role", roleName, {
DatabaseName: "postgres",
})
await handler(removeRole)
} finally {
await client.end()
}
Expand Down
17 changes: 17 additions & 0 deletions test/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,23 @@ export const schemaExists = async (client: Client, schema: string): Promise<bool
return schemas.find((s) => s === schema) !== undefined
}

export const roleGrantedForSchema = async (
client: Client,
schema: string,
role: string
): Promise<boolean> => {
const sql = `select nspname as schema_name, r.rolname as role_name,\
pg_catalog.has_schema_privilege(r.rolname, nspname, 'CREATE') as create_grant,\
pg_catalog.has_schema_privilege(r.rolname, nspname, 'USAGE') as usage_grant\
from pg_namespace pn,pg_catalog.pg_roles r \
where array_to_string(nspacl,',') like '%'||r.rolname||'%' and nspowner > 1 \
and nspname = '${schema}' and r.rolname = '${role}'`
const { rows } = await client.query(sql)
return (
rows.length === 1 && rows[0].create_grant === true && rows[0].usage_grant === true
)
}

const getSchemas = async (client: Client): Promise<string[]> => {
const { rows } = await client.query(
"select schema_name from information_schema.schemata"
Expand Down

0 comments on commit 0bc68b8

Please sign in to comment.