Skip to content

Commit f8fc1fe

Browse files
committed
Add username and password handling from user mapping
Retrieve username and password from user mapping instead of server options.
1 parent 10c07bc commit f8fc1fe

1 file changed

Lines changed: 38 additions & 7 deletions

File tree

src/lib.rs

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -197,17 +197,46 @@ impl ForeignDataWrapper<EtcdFdwError> for EtcdFdw {
197197
let cert_path = server.options.get("ssl_cert").cloned();
198198
let key_path = server.options.get("ssl_key").cloned();
199199
let servername = server.options.get("ssl_servername").cloned();
200-
let username = server.options.get("username").cloned();
201-
let password = server.options.get("password").cloned();
202200

203201
// Parse timeouts with defaults
204202
let connect_timeout = parse_timeout(&server.options, "connect_timeout", config.connect_timeout)?;
205203
let request_timeout = parse_timeout(&server.options, "request_timeout", config.request_timeout)?;
206204

207205
// ssl_cert + ssl_key must be both present or both absent
208-
// username + password must be both present or both absent
209206
require_pair(cert_path.is_some(), key_path.is_some(), EtcdFdwError::CertKeyMismatch(()))?;
210-
require_pair(username.is_some(), password.is_some(), EtcdFdwError::UserPassMismatch(()))?;
207+
208+
let mut username = None;
209+
let mut password = None;
210+
211+
unsafe {
212+
let usermapping = pg_sys::GetUserMapping(pg_sys::GetUserId(), server.server_oid);
213+
let options = (*usermapping).options;
214+
pgrx::memcx::current_context(|mcx| {
215+
let list = pgrx::list::List::<*mut std::ffi::c_void>::downcast_ptr_in_memcx(options, mcx).unwrap();
216+
for option in list.iter() {
217+
let option = *option as *mut pg_sys::DefElem;
218+
let name = std::ffi::CStr::from_ptr((*option).defname);
219+
let value = std::ffi::CStr::from_ptr(pg_sys::defGetString(option));
220+
let name = name.to_str().map_err(|_| {
221+
OptionsError::OptionNameIsInvalidUtf8(
222+
String::from_utf8_lossy(name.to_bytes()).to_string(),
223+
)
224+
});
225+
let value = value.to_str().map_err(|_| {
226+
OptionsError::OptionValueIsInvalidUtf8(
227+
String::from_utf8_lossy(value.to_bytes()).to_string(),
228+
)
229+
});
230+
if let (Ok(name), Ok(value)) = (name, value) {
231+
match name {
232+
"username" => username = Some(value.to_string()),
233+
"password" => password = Some(value.to_string()),
234+
_ => {}
235+
}
236+
}
237+
}
238+
});
239+
}
211240

212241
config = EtcdConfig {
213242
endpoints: vec![connstr],
@@ -613,11 +642,8 @@ impl ForeignDataWrapper<EtcdFdwError> for EtcdFdw {
613642

614643
let cacert_path_exists = check_options_contain(&options, "ssl_ca").is_ok();
615644
let cert_path_exists = check_options_contain(&options, "ssl_cert").is_ok();
616-
let username_exists = check_options_contain(&options, "username").is_ok();
617-
let password_exists = check_options_contain(&options, "password").is_ok();
618645

619646
require_pair(cacert_path_exists, cert_path_exists, EtcdFdwError::CertKeyMismatch(()))?;
620-
require_pair(username_exists, password_exists, EtcdFdwError::UserPassMismatch(()))?;
621647
} else if oid == FOREIGN_TABLE_RELATION_ID {
622648
check_options_contain(&options, "rowid_column")?;
623649

@@ -632,6 +658,11 @@ impl ForeignDataWrapper<EtcdFdwError> for EtcdFdw {
632658
if prefix_exists && key_exists {
633659
return Err(EtcdFdwError::ConflictingPrefixAndKey);
634660
}
661+
} else if oid == pg_sys::BuiltinOid::UserMappingRelationId.value() {
662+
let username_exists = check_options_contain(&options, "username").is_ok();
663+
let password_exists = check_options_contain(&options, "password").is_ok();
664+
665+
require_pair(username_exists, password_exists, EtcdFdwError::UserPassMismatch(()))?;
635666
}
636667
}
637668

0 commit comments

Comments
 (0)