ahri_tre_pgmeta/
workflow_entry.rs1use crate::{PgMetaError, PgMetadataConnection};
4
5pub fn provision_orcid_workflow_entry(
8 connection: &mut PgMetadataConnection,
9 requester_orcid: &str,
10 oauth_group_role: &str,
11) -> Result<String, PgMetaError> {
12 let requester_orcid = requester_orcid.trim();
13 let oauth_group_role = oauth_group_role.trim();
14 if requester_orcid.is_empty() || oauth_group_role.is_empty() {
15 return Err(PgMetaError::Decode {
16 field: "workflow_entry",
17 value: "<redacted>".to_string(),
18 message: "requester ORCID and OAuth group role must not be empty".to_string(),
19 });
20 }
21 let requester_role = normalize_orcid_role(requester_orcid);
22 connection
23 .client()
24 .batch_execute(&membership_sql(&requester_role, oauth_group_role))
25 .map_err(|source| PgMetaError::Write {
26 operation: "provision ORCID workflow entry",
27 source,
28 })?;
29 Ok(requester_role)
30}
31
32fn normalize_orcid_role(orcid: &str) -> String {
33 let orcid = orcid.trim();
34 if orcid.starts_with("orcid_") {
35 orcid.to_string()
36 } else {
37 format!("orcid_{orcid}")
38 }
39}
40
41fn membership_sql(requester_role: &str, oauth_group_role: &str) -> String {
42 format!(
43 "DO $$\nBEGIN\n IF NOT EXISTS (SELECT 1 FROM pg_catalog.pg_roles WHERE rolname = {role_name_literal}) THEN\n EXECUTE format('CREATE ROLE %I LOGIN', {role_name_literal});\n END IF;\n EXECUTE format('GRANT %I TO %I WITH INHERIT TRUE', {group_role_literal}, {role_name_literal});\nEND\n$$;",
44 role_name_literal = sql_literal(requester_role),
45 group_role_literal = sql_literal(oauth_group_role),
46 )
47}
48
49fn sql_literal(value: &str) -> String {
50 format!("'{}'", value.replace('\'', "''"))
51}
52
53#[cfg(test)]
54mod tests {
55 use super::*;
56
57 #[test]
58 fn normalizes_requester_and_requires_inheriting_membership() {
59 assert_eq!(
60 normalize_orcid_role(" 0000-0000-0000-0001 "),
61 "orcid_0000-0000-0000-0001"
62 );
63 assert_eq!(
64 normalize_orcid_role("orcid_0000-0000-0000-0001"),
65 "orcid_0000-0000-0000-0001"
66 );
67 let sql = membership_sql("orcid_0000-0000-0000-0001", "tre-oauth");
68 assert!(sql.contains("CREATE ROLE %I LOGIN"));
69 assert!(sql.contains("GRANT %I TO %I WITH INHERIT TRUE"));
70 }
71}