Skip to content

Commit

Permalink
Merge pull request #77 from collinsmuriuki/mask-client-secret-in-debug
Browse files Browse the repository at this point in the history
Mask client secret and initiator password in debug
  • Loading branch information
c12i authored Nov 9, 2023
2 parents abbfa0d + 2ebf13e commit e373905
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 18 deletions.
13 changes: 2 additions & 11 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ license = "MIT"
chrono = {version = "0.4", optional = true, default-features = false, features = ["clock", "serde"] }
openssl = {version = "0.10", optional = true}
reqwest = {version = "0.11", features = ["json"]}
secrecy = "0.8.0"
serde = {version="1.0", features= ["derive"]}
serde_json = "1.0"
serde_repr = "0.1"
Expand All @@ -25,17 +26,7 @@ tokio = {version = "1", features = ["rt", "rt-multi-thread", "macros"]}
wiremock = "0.5"

[features]
default = [
"account_balance",
"b2b",
"b2c",
"bill_manager",
"c2b_register",
"c2b_simulate",
"express_request",
"transaction_reversal",
"transaction_status"
]
default = ["account_balance", "b2b", "b2c", "bill_manager", "c2b_register", "c2b_simulate", "express_request", "transaction_reversal", "transaction_status"]
account_balance = ["dep:openssl"]
b2b = ["dep:openssl"]
b2c = ["dep:openssl"]
Expand Down
17 changes: 10 additions & 7 deletions src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use openssl::base64;
use openssl::rsa::Padding;
use openssl::x509::X509;
use reqwest::Client as HttpClient;
use secrecy::{ExposeSecret, Secret};
use serde_json::Value;
use std::cell::RefCell;

Expand All @@ -25,8 +26,8 @@ pub type MpesaResult<T> = Result<T, MpesaError>;
#[derive(Clone, Debug)]
pub struct Mpesa<Env: ApiEnvironment> {
client_key: String,
client_secret: String,
initiator_password: RefCell<Option<String>>,
client_secret: Secret<String>,
initiator_password: RefCell<Option<Secret<String>>>,
pub(crate) environment: Env,
pub(crate) http_client: HttpClient,
}
Expand All @@ -42,6 +43,9 @@ impl<'mpesa, Env: ApiEnvironment> Mpesa<Env> {
/// Environment::Sandbox,
/// );
/// ```
///
/// # Panics
/// This method can panic if a TLS backend cannot be initialized for the internal http_client
pub fn new<S: Into<String>>(client_key: S, client_secret: S, environment: Env) -> Self {
let http_client = HttpClient::builder()
.connect_timeout(std::time::Duration::from_millis(10_000))
Expand All @@ -52,7 +56,7 @@ impl<'mpesa, Env: ApiEnvironment> Mpesa<Env> {
.expect("Error building http client");
Self {
client_key: client_key.into(),
client_secret: client_secret.into(),
client_secret: Secret::new(client_secret.into()),
initiator_password: RefCell::new(None),
environment,
http_client,
Expand All @@ -65,7 +69,7 @@ impl<'mpesa, Env: ApiEnvironment> Mpesa<Env> {
let Some(p) = &*self.initiator_password.borrow() else {
return DEFAULT_INITIATOR_PASSWORD.to_owned();
};
p.to_owned()
p.expose_secret().into()
}

/// Optional in development but required for production, you will need to call this method and set your production initiator password.
Expand All @@ -82,7 +86,7 @@ impl<'mpesa, Env: ApiEnvironment> Mpesa<Env> {
/// client.set_initiator_password("your_initiator_password");
/// ```
pub fn set_initiator_password<S: Into<String>>(&self, initiator_password: S) {
*self.initiator_password.borrow_mut() = Some(initiator_password.into());
*self.initiator_password.borrow_mut() = Some(Secret::new(initiator_password.into()));
}

/// Checks if the client can be authenticated
Expand All @@ -102,7 +106,6 @@ impl<'mpesa, Env: ApiEnvironment> Mpesa<Env> {
///
/// # Errors
/// Returns a `MpesaError` on failure
#[allow(clippy::single_char_pattern)]
pub(crate) async fn auth(&self) -> MpesaResult<String> {
let url = format!(
"{}/oauth/v1/generate?grant_type=client_credentials",
Expand All @@ -111,7 +114,7 @@ impl<'mpesa, Env: ApiEnvironment> Mpesa<Env> {
let response = self
.http_client
.get(&url)
.basic_auth(&self.client_key, Some(&self.client_secret))
.basic_auth(&self.client_key, Some(&self.client_secret.expose_secret()))
.send()
.await?;
if response.status().is_success() {
Expand Down

0 comments on commit e373905

Please sign in to comment.