SFDX Auth url completed
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
/target
|
||||||
Generated
+3189
File diff suppressed because it is too large
Load Diff
+13
-1
@@ -1,11 +1,23 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "rustsf_auth"
|
name = "rustsf_auth"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
authors = ["Wim Velzeboer <wim@velzeboer.nl>"]
|
||||||
|
license = "MIT"
|
||||||
|
description = "Salesforce OAuth2 authentication SDK for Rust, supporting JWT, sfdxAuthUrl, ClientCredentials and Web"
|
||||||
|
documentation = "https://docs.rs/rustsf"
|
||||||
|
homepage = "https://github.com/wimvelzeboer/rustsf"
|
||||||
|
repository = "https://github.com/wimvelzeboer/rustsf"
|
||||||
|
readme = "README.md"
|
||||||
|
keywords = ["Salesforce", "API", "sdk", "sfdx", "REST"]
|
||||||
|
categories = ["web-programming", "web-programming::http-client", "database", "development-tools::build-utils"]
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
rust-version = "1.93.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = "1.0.104"
|
anyhow = "1.0.104"
|
||||||
base64 = "0.22"
|
base64 = "0.22"
|
||||||
|
env_logger = "0.11.11"
|
||||||
|
log = "0.4.34"
|
||||||
oauth2 = { version = "5", features = ["reqwest"] }
|
oauth2 = { version = "5", features = ["reqwest"] }
|
||||||
regex = "1"
|
regex = "1"
|
||||||
reqwest = { version = "0.12", features = ["json", "rustls-tls"] }
|
reqwest = { version = "0.12", features = ["json", "rustls-tls"] }
|
||||||
@@ -15,8 +27,8 @@ serde_json = "1"
|
|||||||
sha2 = { version = "0.10", features = ["oid"] }
|
sha2 = { version = "0.10", features = ["oid"] }
|
||||||
thiserror = "2"
|
thiserror = "2"
|
||||||
time = "0.3"
|
time = "0.3"
|
||||||
url = "2"
|
|
||||||
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
|
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
|
||||||
|
url = "2.5.8"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
httpmock = "0.7"
|
httpmock = "0.7"
|
||||||
|
|||||||
@@ -14,10 +14,9 @@
|
|||||||
//! - Export the SFDX Auth url from the CLI
|
//! - Export the SFDX Auth url from the CLI
|
||||||
//! ```bash
|
//! ```bash
|
||||||
//! sf org auth show-sfdx-auth-url --target-org my-org-alias
|
//! sf org auth show-sfdx-auth-url --target-org my-org-alias
|
||||||
//! # or
|
|
||||||
//! sf org auth show-sfdx-auth-url --target-org my-org-alias --json > sfdx_auth_url.json
|
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//! - Copy the sfdxAuthUrl and import it into your application in a save and secure manner,
|
||||||
|
//! and never hardcode it! (like in the example below)
|
||||||
use oauth2::http::header::AUTHORIZATION;
|
use oauth2::http::header::AUTHORIZATION;
|
||||||
use oauth2::http::{HeaderMap, HeaderValue};
|
use oauth2::http::{HeaderMap, HeaderValue};
|
||||||
use rustsf_auth::credentials::SalesforceCredentials;
|
use rustsf_auth::credentials::SalesforceCredentials;
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
//! RustSF Authentication library - SFDX Auth URL Example
|
||||||
|
//!
|
||||||
|
//! In this example, we demonstrate how to use the RustSF Authentication library to authenticate
|
||||||
|
//! with Salesforce using an SFDX auth URL.
|
||||||
|
//! The example includes the necessary imports, constants, and a main function that performs the
|
||||||
|
//! authentication and makes a REST API request.
|
||||||
|
//!
|
||||||
|
//! To create a SFDX Auth url, follow these steps:
|
||||||
|
//! - Download and install the SFDX CLI
|
||||||
|
//! - [Authenticate a Salesforce environment with the SFDX CLI](https://developer.salesforce.com/docs/platform/salesforce-cli-reference/guide/cli_reference_org_login_web.html)
|
||||||
|
//! ```bash
|
||||||
|
//! sf org login web --alias my-org-alias
|
||||||
|
//! ```
|
||||||
|
//! - Export the SFDX Auth url from the CLI
|
||||||
|
//! ```bash
|
||||||
|
//! sf org auth show-sfdx-auth-url --target-org my-org-alias --json > sfdx_auth_url.json
|
||||||
|
//! ```
|
||||||
|
//! - Copy the sfdxAuthUrl and import it into your application in a save and secure manner,
|
||||||
|
//! and never hardcode it! (like in the example below)
|
||||||
|
use oauth2::http::header::AUTHORIZATION;
|
||||||
|
use oauth2::http::{HeaderMap, HeaderValue};
|
||||||
|
use rustsf_auth::{SalesforceCredentials, SfdxAuthJson};
|
||||||
|
use serde::Deserialize;
|
||||||
|
use std::fs;
|
||||||
|
|
||||||
|
pub const CONNECT_TIMEOUT: u64 = 15;
|
||||||
|
pub const REQUEST_TIMEOUT: u64 = 30;
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main(){
|
||||||
|
|
||||||
|
// Load the sfdx auth url
|
||||||
|
let file = fs::File::open("my-org-alias.json")?;
|
||||||
|
let sfdx_auth_json: SfdxAuthJson = serde_json::from_reader(file)?;
|
||||||
|
|
||||||
|
// The Credentials configuration
|
||||||
|
let config = SalesforceCredentials::sfdx_url_json(sfdx_auth_json).unwrap();
|
||||||
|
|
||||||
|
// Constructing the authentication session and connecting to Salesforce
|
||||||
|
let session = config.connect().await.unwrap();
|
||||||
|
|
||||||
|
// Build the headers to include the access token
|
||||||
|
let mut headers = HeaderMap::new();
|
||||||
|
let auth_value = format!("Bearer {}", session.access_token().await.unwrap());
|
||||||
|
headers.insert(AUTHORIZATION, HeaderValue::from_str(&auth_value).unwrap());
|
||||||
|
|
||||||
|
// A REST API request
|
||||||
|
let response = reqwest::Client::builder()
|
||||||
|
.redirect(reqwest::redirect::Policy::none())
|
||||||
|
.connect_timeout(std::time::Duration::from_secs(CONNECT_TIMEOUT))
|
||||||
|
.timeout(std::time::Duration::from_secs(REQUEST_TIMEOUT))
|
||||||
|
.build()
|
||||||
|
.unwrap()
|
||||||
|
.get(format!("{}/services/data", session.instance_url))
|
||||||
|
.headers(headers.clone())
|
||||||
|
.send()
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
if response.status().is_success() {
|
||||||
|
println!("SUCCESS Response: {:?}", response.text().await.unwrap());
|
||||||
|
} else {
|
||||||
|
println!("ERROR Response: {:?}", response.text().await.unwrap());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
max_width = 120
|
||||||
|
hard_tabs = true
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use log::trace;
|
||||||
use crate::credentials::{http_client, required, SalesforceAuthFlow, SalesforceCredentials};
|
use crate::credentials::{http_client, required, SalesforceAuthFlow, SalesforceCredentials};
|
||||||
use crate::salesforce_token_response::SalesforceTokenResponse;
|
use crate::salesforce_token_response::SalesforceTokenResponse;
|
||||||
use crate::SalesforceAuthError;
|
use crate::SalesforceAuthError;
|
||||||
@@ -89,17 +90,27 @@ impl SalesforceCredentials {
|
|||||||
let client_id = required(self.client_id.as_deref(), "client_id")?;
|
let client_id = required(self.client_id.as_deref(), "client_id")?;
|
||||||
let client_secret = required(self.client_secret.as_deref(), "client_secret")?;
|
let client_secret = required(self.client_secret.as_deref(), "client_secret")?;
|
||||||
|
|
||||||
Ok(http_client()?
|
let url = self.token_url()?.url().clone();
|
||||||
.post(self.token_url()?.url().clone())
|
let data = &[
|
||||||
.form(&[
|
("grant_type", "client_credentials"),
|
||||||
("grant_type", "client_credentials"),
|
("client_id", client_id),
|
||||||
("client_id", client_id),
|
("client_secret", client_secret),
|
||||||
("client_secret", client_secret),
|
];
|
||||||
])
|
trace!("Client Credentials auth request: POST {}", url);
|
||||||
.send()
|
|
||||||
.await?
|
let response = http_client()?
|
||||||
.error_for_status()?
|
.post(url)
|
||||||
.json::<SalesforceTokenResponse>()
|
.form(data)
|
||||||
.await?)
|
.send()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let status = response.status();
|
||||||
|
let body = response.text().await.map_err(|e| SalesforceAuthError::Http(e))?;
|
||||||
|
|
||||||
|
trace!("Client Credentials auth response: {}", body);
|
||||||
|
if !status.is_success() { return Err(SalesforceAuthError::OAuth2(body)) }
|
||||||
|
|
||||||
|
Ok(serde_json::from_str::<SalesforceTokenResponse>(&body)
|
||||||
|
.map_err(|e| SalesforceAuthError::TokenExchange(e.to_string()))?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+28
-20
@@ -1,5 +1,6 @@
|
|||||||
use std::sync::RwLock;
|
use std::sync::RwLock;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
use log::trace;
|
||||||
use oauth2::TokenUrl;
|
use oauth2::TokenUrl;
|
||||||
use reqwest::Client;
|
use reqwest::Client;
|
||||||
use crate::{SalesforceAuthError, SalesforceAuthSession, SalesforceAuthToken};
|
use crate::{SalesforceAuthError, SalesforceAuthSession, SalesforceAuthToken};
|
||||||
@@ -8,7 +9,7 @@ use crate::salesforce_token_response::SalesforceTokenResponse;
|
|||||||
mod access_token;
|
mod access_token;
|
||||||
mod client_credentials;
|
mod client_credentials;
|
||||||
mod jwt_bearer;
|
mod jwt_bearer;
|
||||||
mod sfdx_auth_url;
|
pub(crate) mod sfdx_auth_url;
|
||||||
|
|
||||||
/// Supported Salesforce OAuth authentication flows.
|
/// Supported Salesforce OAuth authentication flows.
|
||||||
///
|
///
|
||||||
@@ -170,28 +171,35 @@ impl SalesforceCredentials {
|
|||||||
pub(crate) async fn refresh(&self) -> Result<SalesforceAuthToken, SalesforceAuthError> {
|
pub(crate) async fn refresh(&self) -> Result<SalesforceAuthToken, SalesforceAuthError> {
|
||||||
|
|
||||||
match &self.refresh_token {
|
match &self.refresh_token {
|
||||||
Some(refresh_token) => {
|
|
||||||
let client_id = required(self.client_id.as_deref(), "client_id")?;
|
|
||||||
|
|
||||||
let response = Client::new()
|
|
||||||
.post(self.token_url()?.url().clone())
|
|
||||||
.form(&[
|
|
||||||
("grant_type", "refresh_token"),
|
|
||||||
("client_id", client_id),
|
|
||||||
("refresh_token", refresh_token),
|
|
||||||
// ("client_secret", client_secret.unwrap_or_default()),
|
|
||||||
])
|
|
||||||
.send()
|
|
||||||
.await?
|
|
||||||
.error_for_status()?
|
|
||||||
.json::<SalesforceTokenResponse>()
|
|
||||||
.await?;
|
|
||||||
|
|
||||||
Ok(SalesforceAuthToken::from_token_response(response))
|
|
||||||
},
|
|
||||||
None => {
|
None => {
|
||||||
self.reconnect().await
|
self.reconnect().await
|
||||||
}
|
}
|
||||||
|
Some(refresh_token) => {
|
||||||
|
let client_id = required(self.client_id.as_deref(), "client_id")?;
|
||||||
|
|
||||||
|
let url = self.token_url()?.url().clone();
|
||||||
|
let data = &[
|
||||||
|
("grant_type", "refresh_token"),
|
||||||
|
("client_id", client_id),
|
||||||
|
("refresh_token", refresh_token),
|
||||||
|
];
|
||||||
|
trace!("Token exchange request: POST {} : {:?}", url, data);
|
||||||
|
|
||||||
|
let response = Client::new()
|
||||||
|
.post(url)
|
||||||
|
.form(data)
|
||||||
|
.send()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let status = response.status();
|
||||||
|
let body = response.text().await.map_err(|e| SalesforceAuthError::Http(e))?;
|
||||||
|
|
||||||
|
trace!("Token exchange response: {}", body);
|
||||||
|
if !status.is_success() { return Err(SalesforceAuthError::OAuth2(body)) }
|
||||||
|
|
||||||
|
Ok(serde_json::from_str::<SalesforceAuthToken>(&body)
|
||||||
|
.map_err(|e| SalesforceAuthError::TokenExchange(e.to_string()))?)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,30 @@
|
|||||||
|
use log::trace;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use crate::credentials::{http_client, required, SalesforceAuthFlow, SalesforceCredentials};
|
use crate::credentials::{http_client, required, SalesforceAuthFlow, SalesforceCredentials};
|
||||||
|
use crate::salesforce_auth_token::SalesforceAuthToken;
|
||||||
use crate::SalesforceAuthError;
|
use crate::SalesforceAuthError;
|
||||||
use crate::salesforce_token_response::SalesforceTokenResponse;
|
use crate::salesforce_token_response::SalesforceTokenResponse;
|
||||||
|
|
||||||
|
/// Struct used to deserialize the SFDX auth URL json file,
|
||||||
|
/// which can be created via:.
|
||||||
|
/// ```bash
|
||||||
|
/// sf org auth show-sfdx-auth-url --target-org $ORG-ALIAS --json > sfdx_auth_url.json
|
||||||
|
/// ```
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
pub struct SfdxAuthJson {
|
||||||
|
pub status: String,
|
||||||
|
pub result: SfdxAuthJsonResult,
|
||||||
|
pub warnings: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct SfdxAuthJsonResult {
|
||||||
|
pub sfdx_auth_url: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
impl SalesforceCredentials {
|
impl SalesforceCredentials {
|
||||||
|
|
||||||
/// Creates a configuration for authenticating from an SFDX auth URL.
|
/// Creates a configuration for authenticating from an SFDX auth URL.
|
||||||
@@ -72,6 +94,26 @@ impl SalesforceCredentials {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Creates a configuration for authenticating from an SFDX auth URL.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// Export the SFDX auth URL in a json via:
|
||||||
|
/// ```bash
|
||||||
|
/// sf org auth show-sfdx-auth-url --target-org $ORG-ALIAS --json > sfdx_auth_url.json
|
||||||
|
/// ```
|
||||||
|
/// Then use the generated json file in your application
|
||||||
|
/// ```rust
|
||||||
|
/// use rustsf_auth::{SalesforceCredentials, SfdxAuthJson};
|
||||||
|
///
|
||||||
|
/// let file = fs::File::open("sfdx_auth_url.json")?;
|
||||||
|
/// let sfdx_auth_json: SfdxAuthJson = serde_json::from_reader(file)?;
|
||||||
|
/// let session = config.connect().await.unwrap();
|
||||||
|
/// ```
|
||||||
|
pub fn sfdx_url_json(sfdx_auth_json: SfdxAuthJson) -> Result<Self, SalesforceAuthError> {
|
||||||
|
SalesforceCredentials::sfdx_url(sfdx_auth_json.result.sfdx_auth_url)
|
||||||
|
}
|
||||||
|
|
||||||
/// Authenticates to Salesforce from an SFDX auth URL.
|
/// Authenticates to Salesforce from an SFDX auth URL.
|
||||||
///
|
///
|
||||||
/// The SFDX URL must match:
|
/// The SFDX URL must match:
|
||||||
@@ -112,19 +154,27 @@ impl SalesforceCredentials {
|
|||||||
let client_id = required(self.client_id.as_deref(), "client_id")?;
|
let client_id = required(self.client_id.as_deref(), "client_id")?;
|
||||||
let refresh_token = required(self.refresh_token.as_deref(), "refresh_token")?;
|
let refresh_token = required(self.refresh_token.as_deref(), "refresh_token")?;
|
||||||
|
|
||||||
Ok(http_client()?
|
let url = self.token_url()?.url().clone();
|
||||||
.post(self.token_url()?.url().clone())
|
let data = &[
|
||||||
.form(&[
|
("grant_type", "refresh_token"),
|
||||||
("grant_type", "refresh_token"),
|
("client_id", client_id),
|
||||||
("client_id", client_id),
|
("refresh_token", refresh_token),
|
||||||
("refresh_token", refresh_token),
|
];
|
||||||
// ("client_secret", client_secret.unwrap_or_default()),
|
trace!("SFDX authentication request: POST {} : {:?}", url, data);
|
||||||
])
|
let response = http_client()?
|
||||||
|
.post(url)
|
||||||
|
.form(data)
|
||||||
.send()
|
.send()
|
||||||
.await?
|
.await?;
|
||||||
.error_for_status()?
|
|
||||||
.json::<SalesforceTokenResponse>()
|
let status = response.status();
|
||||||
.await?)
|
let body = response.text().await.map_err(|e| SalesforceAuthError::Http(e))?;
|
||||||
|
|
||||||
|
trace!("SFDX authentication response: {}", body);
|
||||||
|
if !status.is_success() { return Err(SalesforceAuthError::OAuth2(body)) }
|
||||||
|
|
||||||
|
Ok(serde_json::from_str::<SalesforceTokenResponse>(&body)
|
||||||
|
.map_err(|e| SalesforceAuthError::TokenExchange(e.to_string()))?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,6 +182,31 @@ impl SalesforceCredentials {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sfdx_url_json_valid() {
|
||||||
|
let sfdx_auth_json = SfdxAuthJson {
|
||||||
|
status: "0".to_string(),
|
||||||
|
result: SfdxAuthJsonResult {
|
||||||
|
sfdx_auth_url: "force://my_client_id:my_client_secret:my_refresh_token@login.salesforce.com".to_string(),
|
||||||
|
},
|
||||||
|
warnings: vec![],
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = SalesforceCredentials::sfdx_url_json(sfdx_auth_json);
|
||||||
|
|
||||||
|
assert!(result.is_ok());
|
||||||
|
let credentials = result.unwrap();
|
||||||
|
assert_eq!(credentials.flow, SalesforceAuthFlow::SfdxUrl);
|
||||||
|
assert_eq!(credentials.client_id, Some("my_client_id".to_string()));
|
||||||
|
assert_eq!(credentials.client_secret, Some("my_client_secret".to_string()));
|
||||||
|
assert_eq!(credentials.refresh_token, Some("my_refresh_token".to_string()));
|
||||||
|
assert_eq!(credentials.login_url, Some("https://login.salesforce.com".to_string()));
|
||||||
|
assert!(credentials.username.is_none());
|
||||||
|
assert!(credentials.private_key_pem.is_none());
|
||||||
|
assert!(credentials.access_token.is_none());
|
||||||
|
assert!(credentials.instance_url.is_none());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_sfdx_url_valid_with_client_secret() {
|
fn test_sfdx_url_valid_with_client_secret() {
|
||||||
let url = "force://my_client_id:my_client_secret:my_refresh_token@login.salesforce.com";
|
let url = "force://my_client_id:my_client_secret:my_refresh_token@login.salesforce.com";
|
||||||
|
|||||||
@@ -36,6 +36,9 @@ pub enum SalesforceAuthError {
|
|||||||
#[error("HTTP error: {0}")]
|
#[error("HTTP error: {0}")]
|
||||||
Http(#[from] reqwest::Error),
|
Http(#[from] reqwest::Error),
|
||||||
|
|
||||||
|
#[error("Token exchange failure: {0}")]
|
||||||
|
TokenExchange(String),
|
||||||
|
|
||||||
/// Error creating a Salesforce JWT assertion.
|
/// Error creating a Salesforce JWT assertion.
|
||||||
#[error("JWT error: {0}")]
|
#[error("JWT error: {0}")]
|
||||||
Jwt(String),
|
Jwt(String),
|
||||||
|
|||||||
+3
-1
@@ -5,10 +5,12 @@ pub mod error;
|
|||||||
pub(crate) mod salesforce_auth_token;
|
pub(crate) mod salesforce_auth_token;
|
||||||
pub mod salesforce_token_response;
|
pub mod salesforce_token_response;
|
||||||
|
|
||||||
use self::credentials::SalesforceCredentials;
|
|
||||||
use self::error::SalesforceAuthError;
|
use self::error::SalesforceAuthError;
|
||||||
use self::salesforce_auth_token::SalesforceAuthToken;
|
use self::salesforce_auth_token::SalesforceAuthToken;
|
||||||
|
|
||||||
|
pub use self::credentials::SalesforceCredentials;
|
||||||
|
pub use self::credentials::sfdx_auth_url::SfdxAuthJson;
|
||||||
|
|
||||||
/// The default Salesforce production login URL.
|
/// The default Salesforce production login URL.
|
||||||
///
|
///
|
||||||
/// Use this value when authenticating against a production Salesforce org.
|
/// Use this value when authenticating against a production Salesforce org.
|
||||||
|
|||||||
+10
-6
@@ -1,5 +1,5 @@
|
|||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
|
use log::LevelFilter;
|
||||||
use reqwest::header::{AUTHORIZATION, HeaderMap, HeaderValue};
|
use reqwest::header::{AUTHORIZATION, HeaderMap, HeaderValue};
|
||||||
use rustsf_auth::credentials::SalesforceCredentials;
|
use rustsf_auth::credentials::SalesforceCredentials;
|
||||||
|
|
||||||
@@ -18,6 +18,10 @@ pub fn get_http_client() -> Result<reqwest::Client> {
|
|||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
println!("Hello, world!");
|
println!("Hello, world!");
|
||||||
|
env_logger::builder()
|
||||||
|
.filter_level(LevelFilter::Trace)
|
||||||
|
.format_target(false)
|
||||||
|
.init();
|
||||||
|
|
||||||
let url = "https://computing-platform-9537--qa.sandbox.my.salesforce.com/";
|
let url = "https://computing-platform-9537--qa.sandbox.my.salesforce.com/";
|
||||||
let customer_id = "3MVG9xj60O9CjKHpQMaI0gAqe_BibSxfGHYQBII24Bif2Nri7ewsMsz3kEbMr4vch36.q4I.B37EpwOOtg90e";
|
let customer_id = "3MVG9xj60O9CjKHpQMaI0gAqe_BibSxfGHYQBII24Bif2Nri7ewsMsz3kEbMr4vch36.q4I.B37EpwOOtg90e";
|
||||||
@@ -39,15 +43,15 @@ async fn main() {
|
|||||||
/// # Ok(())
|
/// # Ok(())
|
||||||
|
|
||||||
// SFDX AUTH URL
|
// SFDX AUTH URL
|
||||||
let config = SalesforceCredentials::sfdx_url(sfdx_auth_url).unwrap();
|
// let config = SalesforceCredentials::sfdx_url(sfdx_auth_url).unwrap();
|
||||||
/*
|
// /*
|
||||||
// CLIENT CREDENTIALS
|
// CLIENT CREDENTIALS
|
||||||
let config = SalesforceCredentials::client_credentials(
|
let config = SalesforceCredentials::client_credentials(
|
||||||
"https://computing-platform-9537--qa.sandbox.my.salesforce.com",
|
"https://computing-platform-9537--qa.sandbox.my.salesforce.com",
|
||||||
customer_id,
|
customer_id,
|
||||||
customer_secret,
|
customer_secret,
|
||||||
);
|
);
|
||||||
*/
|
// */
|
||||||
println!("Config: {:?}", config);
|
println!("Config: {:?}", config);
|
||||||
|
|
||||||
let session = config.connect().await.unwrap();
|
let session = config.connect().await.unwrap();
|
||||||
@@ -74,7 +78,7 @@ async fn main() {
|
|||||||
} else {
|
} else {
|
||||||
println!("ERROR Response: {:?}", response.text().await.unwrap());
|
println!("ERROR Response: {:?}", response.text().await.unwrap());
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
session.refresh_access_token().await.unwrap();
|
session.refresh_access_token().await.unwrap();
|
||||||
let auth_value = format!("Bearer {}", session.access_token().await.unwrap());
|
let auth_value = format!("Bearer {}", session.access_token().await.unwrap());
|
||||||
println!("token: {}", auth_value);
|
println!("token: {}", auth_value);
|
||||||
@@ -92,5 +96,5 @@ async fn main() {
|
|||||||
} else {
|
} else {
|
||||||
println!("ERROR Response 2: {:?}", response.text().await.unwrap());
|
println!("ERROR Response 2: {:?}", response.text().await.unwrap());
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
use crate::salesforce_token_response::SalesforceTokenResponse;
|
use crate::salesforce_token_response::SalesforceTokenResponse;
|
||||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Deserialize, Clone, PartialEq, Eq)]
|
||||||
pub struct SalesforceAuthToken {
|
pub struct SalesforceAuthToken {
|
||||||
pub(crate) access_token: String,
|
pub(crate) access_token: String,
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user