aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbryan newbold <bnewbold@robocracy.org>2023-03-04 15:50:09 -0800
committerbryan newbold <bnewbold@robocracy.org>2023-03-04 15:50:09 -0800
commit0ea7cd1d360f2ef56ec4dad8ff316db6f2875ac0 (patch)
tree969587f510c2c0dd5ae62ee708b3995278b1142f
parentae9b55206d174a89a84453c7499ca87b3ce6df0f (diff)
downloadadenosine-0ea7cd1d360f2ef56ec4dad8ff316db6f2875ac0.tar.gz
adenosine-0ea7cd1d360f2ef56ec4dad8ff316db6f2875ac0.zip
add basic support for admin 'Basic' auth
-rw-r--r--adenosine/src/xrpc.rs35
1 files changed, 29 insertions, 6 deletions
diff --git a/adenosine/src/xrpc.rs b/adenosine/src/xrpc.rs
index 62f50cd..df7e2ac 100644
--- a/adenosine/src/xrpc.rs
+++ b/adenosine/src/xrpc.rs
@@ -2,6 +2,8 @@ use crate::auth::parse_did_from_jwt;
use crate::identifiers::{Did, Nsid};
use anyhow::anyhow;
pub use anyhow::Result;
+use base64;
+use log::warn;
use reqwest::header;
use serde_json::{json, Value};
use std::collections::HashMap;
@@ -33,10 +35,15 @@ pub struct XrpcClient {
host: String,
auth_token: Option<String>,
refresh_token: Option<String>,
+ admin_password: Option<String>,
}
impl XrpcClient {
- pub fn new(host: String, auth_token: Option<String>) -> Result<Self> {
+ pub fn new(
+ host: String,
+ auth_token: Option<String>,
+ admin_password: Option<String>,
+ ) -> Result<Self> {
let http_client = reqwest::blocking::Client::builder()
.user_agent(APP_USER_AGENT)
.timeout(Duration::from_secs(30))
@@ -49,11 +56,27 @@ impl XrpcClient {
host,
auth_token: auth_token.clone(),
refresh_token: auth_token,
+ admin_password,
})
}
- fn auth_headers(&self) -> reqwest::header::HeaderMap {
+ fn auth_headers(&self, endpoint: &str) -> reqwest::header::HeaderMap {
let mut headers = header::HeaderMap::new();
+ if endpoint == "com.atproto.account.createInviteCode"
+ || endpoint.starts_with("com.atproto.admin.")
+ {
+ if let Some(admin_password) = &self.admin_password {
+ let enc =
+ base64::encode_config(format!("admin:{admin_password}"), base64::STANDARD);
+ let mut auth_value = header::HeaderValue::from_str(&format!("Basic {enc}"))
+ .expect("header formatting");
+ auth_value.set_sensitive(true);
+ headers.insert(header::AUTHORIZATION, auth_value);
+ return headers;
+ } else {
+ warn!("endpoint requires admin auth, but password not supplied: {endpoint}")
+ };
+ };
if let Some(token) = &self.auth_token {
let mut auth_value = header::HeaderValue::from_str(&format!("Bearer {token}"))
.expect("header formatting");
@@ -107,7 +130,7 @@ impl XrpcClient {
let res = self
.http_client
.get(format!("{}/xrpc/{nsid}", self.host))
- .headers(self.auth_headers())
+ .headers(self.auth_headers(nsid))
.query(&params)
.send()?;
// TODO: refactor this error handling stuff into single method
@@ -138,7 +161,7 @@ impl XrpcClient {
let res = self
.http_client
.get(format!("{}/xrpc/{}", self.host, nsid))
- .headers(self.auth_headers())
+ .headers(self.auth_headers(nsid))
.query(&params)
.send()?;
if res.status() == 400 {
@@ -174,7 +197,7 @@ impl XrpcClient {
let mut req = self
.http_client
.post(format!("{}/xrpc/{}", self.host, nsid))
- .headers(self.auth_headers())
+ .headers(self.auth_headers(nsid))
.query(&params);
req = if let Some(b) = body {
req.json(&b)
@@ -215,7 +238,7 @@ impl XrpcClient {
let res = self
.http_client
.post(format!("{}/xrpc/{}", self.host, nsid))
- .headers(self.auth_headers())
+ .headers(self.auth_headers(nsid))
.query(&params)
.header(reqwest::header::CONTENT_TYPE, "application/cbor")
.body(buf)