* create_role implements the core logic for createRole command */
| 199 | * create_role implements the core logic for createRole command |
| 200 | */ |
| 201 | Datum |
| 202 | create_role(pgbson *createRoleBson) |
| 203 | { |
| 204 | if (!EnableRoleCrud) |
| 205 | { |
| 206 | ereport(ERROR, (errcode(ERRCODE_DOCUMENTDB_COMMANDNOTSUPPORTED), |
| 207 | errmsg("The CreateRole command is currently unsupported."), |
| 208 | errdetail_log( |
| 209 | "The CreateRole command is currently unsupported."))); |
| 210 | } |
| 211 | |
| 212 | ReportFeatureUsage(FEATURE_ROLE_CREATE); |
| 213 | |
| 214 | if (!IsMetadataCoordinator()) |
| 215 | { |
| 216 | StringInfo createRoleQuery = makeStringInfo(); |
| 217 | appendStringInfo(createRoleQuery, |
| 218 | "SELECT %s.create_role(%s::%s.bson)", |
| 219 | ApiSchemaNameV2, |
| 220 | quote_literal_cstr(PgbsonToHexadecimalString(createRoleBson)), |
| 221 | CoreSchemaNameV2); |
| 222 | DistributedRunCommandResult result = RunCommandOnMetadataCoordinator( |
| 223 | createRoleQuery->data); |
| 224 | |
| 225 | if (!result.success) |
| 226 | { |
| 227 | ereport(ERROR, (errcode(ERRCODE_DOCUMENTDB_INTERNALERROR), |
| 228 | errmsg( |
| 229 | "Create role operation failed: %s", |
| 230 | text_to_cstring(result.response)), |
| 231 | errdetail_log( |
| 232 | "Create role operation failed: %s", |
| 233 | text_to_cstring(result.response)))); |
| 234 | } |
| 235 | |
| 236 | pgbson_writer finalWriter; |
| 237 | PgbsonWriterInit(&finalWriter); |
| 238 | PgbsonWriterAppendInt32(&finalWriter, "ok", 2, 1); |
| 239 | return PointerGetDatum(PgbsonWriterGetPgbson(&finalWriter)); |
| 240 | } |
| 241 | |
| 242 | CreateRoleSpec createRoleSpec = { |
| 243 | .roleName = NULL, |
| 244 | .parentRoles = CreateParentRolesHashSet(), |
| 245 | .customPrivileges = NIL |
| 246 | }; |
| 247 | ParseCreateRoleSpec(createRoleBson, &createRoleSpec); |
| 248 | |
| 249 | /* Create the specified role in the database */ |
| 250 | StringInfo createRoleInfo = makeStringInfo(); |
| 251 | appendStringInfo(createRoleInfo, "CREATE ROLE %s", quote_identifier( |
| 252 | createRoleSpec.roleName)); |
| 253 | |
| 254 | bool readOnly = false; |
| 255 | bool isNull = false; |
| 256 | ExtensionExecuteQueryViaSPI(createRoleInfo->data, readOnly, SPI_OK_UTILITY, &isNull); |
| 257 | |
| 258 | /* Validate and grant inherited roles to the new role */ |
no test coverage detected