( options: Options, instanceId: string, databaseId: string, grantedRole: string, granteeRole: string, )
| 52 | // Returns true if "grantedRole" is granted to "granteeRole" and false otherwise. |
| 53 | // Throw an error if commands fails due to another reason like connection issues. |
| 54 | export async function checkSQLRoleIsGranted( |
| 55 | options: Options, |
| 56 | instanceId: string, |
| 57 | databaseId: string, |
| 58 | grantedRole: string, |
| 59 | granteeRole: string, |
| 60 | ): Promise<boolean> { |
| 61 | const checkCmd = ` |
| 62 | DO $$ |
| 63 | DECLARE |
| 64 | role_count INTEGER; |
| 65 | BEGIN |
| 66 | -- Count the number of rows matching the criteria |
| 67 | SELECT COUNT(*) |
| 68 | INTO role_count |
| 69 | FROM |
| 70 | pg_auth_members m |
| 71 | JOIN |
| 72 | pg_roles grantee ON grantee.oid = m.member |
| 73 | JOIN |
| 74 | pg_roles granted ON granted.oid = m.roleid |
| 75 | JOIN |
| 76 | pg_roles grantor ON grantor.oid = m.grantor |
| 77 | WHERE |
| 78 | granted.rolname = '${grantedRole}' |
| 79 | AND grantee.rolname = '${granteeRole}'; |
| 80 | |
| 81 | -- If no rows were found, raise an exception |
| 82 | IF role_count = 0 THEN |
| 83 | RAISE EXCEPTION 'Role "%", is not granted to role "%".', '${grantedRole}', '${granteeRole}'; |
| 84 | END IF; |
| 85 | END $$; |
| 86 | `; |
| 87 | try { |
| 88 | await executeSqlCmdsAsIamUser(options, instanceId, databaseId, [checkCmd], /** silent=*/ true); |
| 89 | return true; |
| 90 | } catch (e) { |
| 91 | // We only return false after we confirm the error is indeed because the role isn't granted. |
| 92 | // Otherwise we propagate the error. |
| 93 | if (e instanceof FirebaseError && e.message.includes("not granted to role")) { |
| 94 | return false; |
| 95 | } |
| 96 | logger.error(`Role Check Failed: ${e}`); |
| 97 | throw e; |
| 98 | } |
| 99 | } |
| 100 | |
| 101 | // Sets up all FDC roles (owner, writer, and reader). |
| 102 | // Granting roles to users is done by the caller. |
no test coverage detected
searching dependent graphs…