MCPcopy Create free account
hub / github.com/NodeDB-Lab/nodedb / create_role

Function create_role

nodedb/src/control/server/pgwire/ddl/role.rs:15–74  ·  view source on GitHub ↗

CREATE ROLE [IF NOT EXISTS] [INHERIT ]

(
    state: &SharedState,
    identity: &AuthenticatedIdentity,
    parts: &[&str],
)

Source from the content-addressed store, hash-verified

13
14/// CREATE ROLE [IF NOT EXISTS] <name> [INHERIT <parent>]
15pub fn create_role(
16 state: &SharedState,
17 identity: &AuthenticatedIdentity,
18 parts: &[&str],
19) -> PgWireResult<Vec<Response>> {
20 require_tenant_admin(identity, "create roles")?;
21
22 let (if_not_exists, parts) = strip_if_not_exists(parts, 2);
23
24 if parts.len() < 3 {
25 return Err(sqlstate_error(
26 "42601",
27 "syntax: CREATE ROLE [IF NOT EXISTS] <name> [INHERIT <parent>]",
28 ));
29 }
30
31 let name = parts[2];
32
33 // `IF NOT EXISTS`: re-creating an existing role is a no-op success.
34 if if_not_exists && state.roles.get_role(name).is_some() {
35 return Ok(vec![Response::Execution(Tag::new("CREATE ROLE"))]);
36 }
37
38 let parent = if parts.len() >= 5 && parts[3].eq_ignore_ascii_case("INHERIT") {
39 Some(parts[4])
40 } else {
41 None
42 };
43
44 // Build the `StoredRole` on the proposer (runs the same
45 // validation as `create_role` but without touching state).
46 let stored = state
47 .roles
48 .prepare_role(name, identity.tenant_id, parent)
49 .map_err(|e| sqlstate_error("42710", &e.to_string()))?;
50
51 let entry = crate::control::catalog_entry::CatalogEntry::PutRole(Box::new(stored.clone()));
52 let log_index = crate::control::metadata_proposer::propose_catalog_entry(state, &entry)
53 .map_err(|e| sqlstate_error("XX000", &format!("metadata propose: {e}")))?;
54 if log_index == 0
55 && let Some(catalog) = state.credentials.catalog()
56 {
57 catalog
58 .put_role(&stored)
59 .map_err(|e| sqlstate_error("XX000", &format!("catalog write: {e}")))?;
60 state.roles.install_replicated_role(&stored);
61 }
62
63 state.audit_record(
64 AuditEvent::PrivilegeChange,
65 Some(identity.tenant_id),
66 &identity.username,
67 &format!(
68 "created role '{name}'{}",
69 parent.map_or(String::new(), |p| format!(" inheriting from '{p}'"))
70 ),
71 );
72

Callers 1

dispatchFunction · 0.85

Calls 13

require_tenant_adminFunction · 0.85
strip_if_not_existsFunction · 0.85
propose_catalog_entryFunction · 0.85
get_roleMethod · 0.80
prepare_roleMethod · 0.80
to_stringMethod · 0.80
put_roleMethod · 0.80
audit_recordMethod · 0.80
sqlstate_errorFunction · 0.70
lenMethod · 0.45
cloneMethod · 0.45

Tested by

no test coverage detected