stuff
This commit is contained in:
+60
-47
@@ -16,9 +16,7 @@ use rsa::RsaPrivateKey;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sha2::Sha256;
|
use sha2::Sha256;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use thiserror::Error;
|
|
||||||
use time::OffsetDateTime;
|
use time::OffsetDateTime;
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
|
|
||||||
/// The default Salesforce production login URL.
|
/// The default Salesforce production login URL.
|
||||||
@@ -392,6 +390,13 @@ pub struct SalesforceAuthSession {
|
|||||||
/// Salesforce identity service URL, when returned by Salesforce.
|
/// Salesforce identity service URL, when returned by Salesforce.
|
||||||
pub id: Option<String>,
|
pub id: Option<String>,
|
||||||
|
|
||||||
|
/// OAuth refresh token, when available.
|
||||||
|
/// Salesforce organization ID parsed from the identity service URL.
|
||||||
|
pub org_id: Option<String>,
|
||||||
|
|
||||||
|
/// Salesforce user ID parsed from the identity service URL.
|
||||||
|
pub user_id: Option<String>,
|
||||||
|
|
||||||
/// OAuth refresh token, when available.
|
/// OAuth refresh token, when available.
|
||||||
pub refresh_token: Option<String>,
|
pub refresh_token: Option<String>,
|
||||||
|
|
||||||
@@ -659,54 +664,29 @@ pub async fn authenticate_client_credentials(
|
|||||||
client_id: &str,
|
client_id: &str,
|
||||||
client_secret: &str,
|
client_secret: &str,
|
||||||
) -> Result<SalesforceAuthSession, SalesforceAuthError> {
|
) -> Result<SalesforceAuthSession, SalesforceAuthError> {
|
||||||
println!("authenticate_client_credentials");
|
let response = Client::builder()
|
||||||
println!("login url {}", login_url);
|
|
||||||
println!("client Id {}", client_id);
|
|
||||||
println!("client secret {}", client_secret);
|
|
||||||
|
|
||||||
let http_client = Client::builder()
|
|
||||||
.redirect(reqwest::redirect::Policy::none())
|
.redirect(reqwest::redirect::Policy::none())
|
||||||
.timeout(Duration::from_secs(30))
|
.timeout(Duration::from_secs(30))
|
||||||
.build()?;
|
.build()?
|
||||||
let token_url = TokenUrl::new(format!(
|
.post(token_url(login_url)?.url().clone())
|
||||||
"{}/services/oauth2/token",
|
.form(&[
|
||||||
login_url.trim_end_matches('/')
|
("grant_type", "client_credentials"),
|
||||||
// "http://localhost:3000"
|
("client_id", client_id),
|
||||||
))
|
("client_secret", client_secret),
|
||||||
.map_err(|error| SalesforceAuthError::OAuth2(error.to_string()))?;
|
])
|
||||||
|
.send()
|
||||||
|
.await?
|
||||||
|
.error_for_status()?
|
||||||
|
.json::<SalesforceTokenResponse>()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
to_session(
|
||||||
let oauth_client = BasicClient::new(ClientId::new(client_id.to_string()))
|
response,
|
||||||
.set_client_secret(ClientSecret::new(client_secret.to_string()))
|
None,
|
||||||
.set_token_uri(token_url);
|
Some(client_id.to_string()),
|
||||||
|
Some(client_secret.to_string()),
|
||||||
let token_response: StandardTokenResponse<oauth2::EmptyExtraTokenFields, BasicTokenType> =
|
Some(login_url.to_string()),
|
||||||
oauth_client
|
)
|
||||||
.exchange_client_credentials()
|
|
||||||
// .add_scope(Scope::new("api".to_string()))
|
|
||||||
.request_async(&http_client)
|
|
||||||
.await
|
|
||||||
.map_err(|error| SalesforceAuthError::OAuth2(error.to_string()))?;
|
|
||||||
|
|
||||||
let access_token = token_response.access_token().secret().to_string();
|
|
||||||
|
|
||||||
println!("asfasf {}", client_id);
|
|
||||||
|
|
||||||
|
|
||||||
Ok(SalesforceAuthSession {
|
|
||||||
token: RwLock::new(SalesforceAuthToken {
|
|
||||||
access_token: "asdf".to_string(),
|
|
||||||
token_type: Some("Bearer".to_string()),
|
|
||||||
issued_at: None,
|
|
||||||
signature: None,
|
|
||||||
}),
|
|
||||||
instance_url: login_url.trim_end_matches('/').to_string(),
|
|
||||||
id: None,
|
|
||||||
refresh_token: None,
|
|
||||||
client_id: Some(client_id.to_string()),
|
|
||||||
client_secret: Some(client_secret.to_string()),
|
|
||||||
login_url: Some(login_url.to_string()),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Authenticates to Salesforce using the JWT bearer flow.
|
/// Authenticates to Salesforce using the JWT bearer flow.
|
||||||
@@ -772,6 +752,31 @@ fn salesforce_token_endpoint(login_url: &str) -> String {
|
|||||||
format!("{}/services/oauth2/token", login_url.trim_end_matches('/'))
|
format!("{}/services/oauth2/token", login_url.trim_end_matches('/'))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_salesforce_identity_ids(id_url: Option<&str>) -> (Option<String>, Option<String>) {
|
||||||
|
let Some(id_url) = id_url else {
|
||||||
|
return (None, None);
|
||||||
|
};
|
||||||
|
|
||||||
|
let segments = id_url
|
||||||
|
.trim_end_matches('/')
|
||||||
|
.split('/')
|
||||||
|
.filter(|segment| !segment.is_empty())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
if segments.len() < 2 {
|
||||||
|
return (None, None);
|
||||||
|
}
|
||||||
|
|
||||||
|
let org_id = segments
|
||||||
|
.get(segments.len() - 2)
|
||||||
|
.map(|value| (*value).to_string());
|
||||||
|
|
||||||
|
let user_id = segments
|
||||||
|
.last()
|
||||||
|
.map(|value| (*value).to_string());
|
||||||
|
|
||||||
|
(org_id, user_id)
|
||||||
|
}
|
||||||
|
|
||||||
fn to_session(
|
fn to_session(
|
||||||
response: SalesforceTokenResponse,
|
response: SalesforceTokenResponse,
|
||||||
@@ -784,6 +789,8 @@ fn to_session(
|
|||||||
.instance_url
|
.instance_url
|
||||||
.ok_or(SalesforceAuthError::MissingRequiredField("instance_url"))?;
|
.ok_or(SalesforceAuthError::MissingRequiredField("instance_url"))?;
|
||||||
|
|
||||||
|
let (org_id, user_id) = parse_salesforce_identity_ids(response.id.as_deref());
|
||||||
|
|
||||||
Ok(SalesforceAuthSession {
|
Ok(SalesforceAuthSession {
|
||||||
token: RwLock::new(SalesforceAuthToken {
|
token: RwLock::new(SalesforceAuthToken {
|
||||||
access_token: response.access_token,
|
access_token: response.access_token,
|
||||||
@@ -793,6 +800,8 @@ fn to_session(
|
|||||||
}),
|
}),
|
||||||
instance_url,
|
instance_url,
|
||||||
id: response.id,
|
id: response.id,
|
||||||
|
org_id,
|
||||||
|
user_id,
|
||||||
refresh_token: response.refresh_token.or(refresh_token),
|
refresh_token: response.refresh_token.or(refresh_token),
|
||||||
client_id,
|
client_id,
|
||||||
client_secret,
|
client_secret,
|
||||||
@@ -839,6 +848,8 @@ pub fn authenticate_access_token(
|
|||||||
}),
|
}),
|
||||||
instance_url: instance_url.trim_end_matches('/').to_string(),
|
instance_url: instance_url.trim_end_matches('/').to_string(),
|
||||||
id: None,
|
id: None,
|
||||||
|
org_id: None,
|
||||||
|
user_id: None,
|
||||||
refresh_token,
|
refresh_token,
|
||||||
client_id,
|
client_id,
|
||||||
client_secret,
|
client_secret,
|
||||||
@@ -1134,6 +1145,8 @@ async fn fetch_salesforce_token_response_from_access_token(
|
|||||||
}),
|
}),
|
||||||
instance_url: login_url.trim_end_matches('/').to_string(),
|
instance_url: login_url.trim_end_matches('/').to_string(),
|
||||||
id: None,
|
id: None,
|
||||||
|
org_id: None,
|
||||||
|
user_id: None,
|
||||||
refresh_token: None,
|
refresh_token: None,
|
||||||
client_id: None,
|
client_id: None,
|
||||||
client_secret: None,
|
client_secret: None,
|
||||||
|
|||||||
+18
-4
@@ -58,18 +58,32 @@ async fn main() {
|
|||||||
//Default header
|
//Default header
|
||||||
headers.insert("Accept", HeaderValue::from_static("application/json"));
|
headers.insert("Accept", HeaderValue::from_static("application/json"));
|
||||||
|
|
||||||
|
// Get API Versions
|
||||||
let response = get_http_client().unwrap()
|
let response = get_http_client().unwrap()
|
||||||
.get(format!("{}/services/data", session.instance_url))
|
.get(format!("{}/services/data", session.instance_url))
|
||||||
.headers(headers)
|
.headers(headers.clone())
|
||||||
.send()
|
.send()
|
||||||
.await
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|
||||||
if response.status().is_success() {
|
if response.status().is_success() {
|
||||||
println!("SUCCESS Response: {:?}", response.text().await.unwrap());
|
println!("SUCCESS Response: {:?}", response.text().await.unwrap());
|
||||||
} else {
|
} else {
|
||||||
println!("ERROR Response: {:?}", response.text().await.unwrap());
|
println!("ERROR Response: {:?}", response.text().await.unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
session.refresh_access_token().await.unwrap();
|
||||||
|
|
||||||
|
// Get LIMITs Versions
|
||||||
|
let response = get_http_client().unwrap()
|
||||||
|
.get(format!("{}/services/data/v67.0/limits", session.instance_url))
|
||||||
|
.headers(headers)
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
if response.status().is_success() {
|
||||||
|
println!("SUCCESS Response 2: {:?}", response.text().await.unwrap());
|
||||||
|
} else {
|
||||||
|
println!("ERROR Response 2: {:?}", response.text().await.unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user