Add tests
This commit is contained in:
@@ -1,7 +1,6 @@
|
|||||||
use crate::credentials::{required, SalesforceAuthFlow, SalesforceCredentials};
|
use crate::credentials::{required, SalesforceAuthFlow, SalesforceCredentials};
|
||||||
use crate::error::SalesforceAuthError;
|
use crate::error::SalesforceAuthError;
|
||||||
use crate::salesforce_token_response::SalesforceTokenResponse;
|
use crate::salesforce_token_response::SalesforceTokenResponse;
|
||||||
use crate::SalesforceAuthSession;
|
|
||||||
|
|
||||||
impl SalesforceCredentials {
|
impl SalesforceCredentials {
|
||||||
/// Creates a configuration for using an existing Salesforce access token.
|
/// Creates a configuration for using an existing Salesforce access token.
|
||||||
|
|||||||
@@ -10,9 +10,8 @@ use rsa::pkcs8::DecodePrivateKey;
|
|||||||
use rsa::pkcs1v15::SigningKey;
|
use rsa::pkcs1v15::SigningKey;
|
||||||
use rsa::signature::{RandomizedSigner, SignatureEncoding};
|
use rsa::signature::{RandomizedSigner, SignatureEncoding};
|
||||||
use rsa::RsaPrivateKey;
|
use rsa::RsaPrivateKey;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::Serialize;
|
||||||
use sha2::Sha256;
|
use sha2::Sha256;
|
||||||
use std::time::Duration;
|
|
||||||
use time::OffsetDateTime;
|
use time::OffsetDateTime;
|
||||||
use crate::salesforce_token_endpoint;
|
use crate::salesforce_token_endpoint;
|
||||||
|
|
||||||
|
|||||||
@@ -131,11 +131,12 @@ impl SalesforceCredentials {
|
|||||||
|
|
||||||
let (org_id, user_id) = parse_salesforce_identity_ids(token_response.id.as_deref());
|
let (org_id, user_id) = parse_salesforce_identity_ids(token_response.id.as_deref());
|
||||||
|
|
||||||
let instance_url = match (&self.instance_url, &self.login_url) {
|
let instance_url = match (&token_response.instance_url, &self.instance_url, &self.login_url) {
|
||||||
(Some(url), None)
|
| (Some(url), _, _ )
|
||||||
| (None, Some(url))
|
| (_, Some(url), None)
|
||||||
| (Some(url), Some(_)) => { url },
|
| (_, None, Some(url))
|
||||||
(None, None) => "http://login.salesforce.com",
|
| (_, Some(url), _) => { url },
|
||||||
|
(_, _, _) => "http://login.salesforce.com",
|
||||||
}.to_string();
|
}.to_string();
|
||||||
|
|
||||||
Ok(SalesforceAuthSession {
|
Ok(SalesforceAuthSession {
|
||||||
|
|||||||
@@ -128,4 +128,94 @@ impl SalesforceCredentials {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sfdx_url_valid_with_client_secret() {
|
||||||
|
let url = "force://my_client_id:my_client_secret:my_refresh_token@login.salesforce.com";
|
||||||
|
let result = SalesforceCredentials::sfdx_url(url);
|
||||||
|
|
||||||
|
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]
|
||||||
|
fn test_sfdx_url_valid_without_client_secret() {
|
||||||
|
let url = "force://PlatformCLI::refresh_token_value@test.salesforce.com";
|
||||||
|
let result = SalesforceCredentials::sfdx_url(url);
|
||||||
|
|
||||||
|
assert!(result.is_ok());
|
||||||
|
let credentials = result.unwrap();
|
||||||
|
assert_eq!(credentials.flow, SalesforceAuthFlow::SfdxUrl);
|
||||||
|
assert_eq!(credentials.client_id, Some("PlatformCLI".to_string()));
|
||||||
|
assert_eq!(credentials.client_secret, None);
|
||||||
|
assert_eq!(credentials.refresh_token, Some("refresh_token_value".to_string()));
|
||||||
|
assert_eq!(credentials.login_url, Some("https://test.salesforce.com".to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sfdx_url_with_base64_refresh_token() {
|
||||||
|
let url = "force://client123:secret456:dGVzdF90b2tlbl92YWx1ZQ==@login.salesforce.com";
|
||||||
|
let result = SalesforceCredentials::sfdx_url(url);
|
||||||
|
|
||||||
|
assert!(result.is_ok());
|
||||||
|
let credentials = result.unwrap();
|
||||||
|
assert_eq!(credentials.client_id, Some("client123".to_string()));
|
||||||
|
assert_eq!(credentials.client_secret, Some("secret456".to_string()));
|
||||||
|
assert_eq!(credentials.refresh_token, Some("dGVzdF90b2tlbl92YWx1ZQ==".to_string()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sfdx_url_invalid_format() {
|
||||||
|
let url = "https://invalid-format.com";
|
||||||
|
let result = SalesforceCredentials::sfdx_url(url);
|
||||||
|
|
||||||
|
assert!(result.is_err());
|
||||||
|
assert!(matches!(result.unwrap_err(), SalesforceAuthError::InvalidSfdxUrl));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sfdx_url_missing_components() {
|
||||||
|
let url = "force://client_id:@login.salesforce.com";
|
||||||
|
let result = SalesforceCredentials::sfdx_url(url);
|
||||||
|
|
||||||
|
assert!(result.is_err());
|
||||||
|
assert!(matches!(result.unwrap_err(), SalesforceAuthError::InvalidSfdxUrl));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sfdx_url_invalid_scheme() {
|
||||||
|
let url = "http://client_id:secret:token@login.salesforce.com";
|
||||||
|
let result = SalesforceCredentials::sfdx_url(url);
|
||||||
|
|
||||||
|
assert!(result.is_err());
|
||||||
|
assert!(matches!(result.unwrap_err(), SalesforceAuthError::InvalidSfdxUrl));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_sfdx_url_with_special_characters() {
|
||||||
|
let url = "force://client.id-123:secret_456:refresh-token.value@test-env.salesforce.com";
|
||||||
|
let result = SalesforceCredentials::sfdx_url(url);
|
||||||
|
|
||||||
|
assert!(result.is_ok());
|
||||||
|
let credentials = result.unwrap();
|
||||||
|
assert_eq!(credentials.client_id, Some("client.id-123".to_string()));
|
||||||
|
assert_eq!(credentials.client_secret, Some("secret_456".to_string()));
|
||||||
|
assert_eq!(credentials.refresh_token, Some("refresh-token.value".to_string()));
|
||||||
|
assert_eq!(credentials.login_url, Some("https://test-env.salesforce.com".to_string()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+3
-44
@@ -1,22 +1,4 @@
|
|||||||
use base64::Engine;
|
|
||||||
use base64::engine::general_purpose::URL_SAFE_NO_PAD;
|
|
||||||
use oauth2::{
|
|
||||||
AuthUrl, ClientId, ClientSecret, EndpointNotSet, EndpointSet, RefreshToken, Scope,
|
|
||||||
StandardTokenResponse, TokenResponse, TokenUrl,
|
|
||||||
basic::{BasicClient, BasicTokenType},
|
|
||||||
};
|
|
||||||
use rsa::pkcs1::DecodeRsaPrivateKey;
|
|
||||||
use rsa::pkcs8::DecodePrivateKey;
|
|
||||||
use regex::Regex;
|
|
||||||
use reqwest::Client;
|
|
||||||
use rsa::pkcs1v15::SigningKey;
|
|
||||||
use std::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
|
use std::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||||
use rsa::signature::{RandomizedSigner, SignatureEncoding};
|
|
||||||
use rsa::RsaPrivateKey;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
use sha2::Sha256;
|
|
||||||
use std::time::Duration;
|
|
||||||
use time::OffsetDateTime;
|
|
||||||
|
|
||||||
pub mod credentials;
|
pub mod credentials;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
@@ -24,7 +6,6 @@ pub(crate) mod salesforce_auth_token;
|
|||||||
pub mod salesforce_token_response;
|
pub mod salesforce_token_response;
|
||||||
|
|
||||||
use self::credentials::SalesforceCredentials;
|
use self::credentials::SalesforceCredentials;
|
||||||
use self::salesforce_token_response::SalesforceTokenResponse;
|
|
||||||
use self::error::SalesforceAuthError;
|
use self::error::SalesforceAuthError;
|
||||||
use self::salesforce_auth_token::SalesforceAuthToken;
|
use self::salesforce_auth_token::SalesforceAuthToken;
|
||||||
|
|
||||||
@@ -41,7 +22,6 @@ use self::salesforce_auth_token::SalesforceAuthToken;
|
|||||||
/// ```
|
/// ```
|
||||||
pub const DEFAULT_SALESFORCE_LOGIN_URL: &str = "https://login.salesforce.com";
|
pub const DEFAULT_SALESFORCE_LOGIN_URL: &str = "https://login.salesforce.com";
|
||||||
|
|
||||||
const DEFAULT_ACCESS_TOKEN_TTL_SECONDS: i64 = 2 * 60 * 60;
|
|
||||||
|
|
||||||
/// Authenticated Salesforce session data.
|
/// Authenticated Salesforce session data.
|
||||||
///
|
///
|
||||||
@@ -161,35 +141,13 @@ impl SalesforceAuthSession {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Returns `true` when this session's access token should be refreshed.
|
|
||||||
///
|
|
||||||
/// If `issued_at` is missing or cannot be parsed, the token is treated as
|
|
||||||
/// expired so callers fail safe and obtain a fresh token.
|
|
||||||
fn is_access_token_expired(&self) -> bool {
|
|
||||||
let token = self.token();
|
|
||||||
|
|
||||||
let Some(issued_at) = token.issued_at.as_deref() else {
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
let Ok(issued_at_millis) = issued_at.parse::<i128>() else {
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
let issued_at_seconds = issued_at_millis / 1_000;
|
|
||||||
let expires_at = issued_at_seconds + i128::from(DEFAULT_ACCESS_TOKEN_TTL_SECONDS);
|
|
||||||
let now = i128::from(OffsetDateTime::now_utc().unix_timestamp());
|
|
||||||
|
|
||||||
now >= expires_at
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn salesforce_token_endpoint(login_url: &str) -> String {
|
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('/'))
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
@@ -402,4 +360,5 @@ iPVvh9x50hP1hS1U1WlZTNhmFLj1gCwCKPwqZzIgVjWgltxO8+/ftA==
|
|||||||
assert_eq!(session.access_token, "access-token");
|
assert_eq!(session.access_token, "access-token");
|
||||||
assert_eq!(session.instance_url, "https://example.my.salesforce.com");
|
assert_eq!(session.instance_url, "https://example.my.salesforce.com");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
Reference in New Issue
Block a user