Skip to content

Commit 852a723

Browse files
committed
Add debugLogFileLocation parameter to constructor and mask API credentials in log
1 parent 562a14f commit 852a723

File tree

2 files changed

+98
-7
lines changed

2 files changed

+98
-7
lines changed

src/ConvertKit_API.php

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,12 @@ class ConvertKit_API
7777
/**
7878
* Constructor for ConvertKitAPI instance
7979
*
80-
* @param string $api_key ConvertKit API Key.
81-
* @param string $api_secret ConvertKit API Secret.
82-
* @param boolean $debug Log requests to debugger.
80+
* @param string $api_key ConvertKit API Key.
81+
* @param string $api_secret ConvertKit API Secret.
82+
* @param boolean $debug Log requests to debugger.
83+
* @param string $debugLogFileLocation Path and filename of debug file to write to.
8384
*/
84-
public function __construct(string $api_key, string $api_secret, bool $debug = false)
85+
public function __construct(string $api_key, string $api_secret, bool $debug = false, string $debugLogFileLocation = '')
8586
{
8687
$this->api_key = $api_key;
8788
$this->api_secret = $api_secret;
@@ -97,8 +98,13 @@ public function __construct(string $api_key, string $api_secret, bool $debug = f
9798
);
9899

99100
if ($debug) {
101+
// If no debug log file location specified, define a default.
102+
if (empty($debugLogFileLocation)) {
103+
$debugLogFileLocation = __DIR__ . '/logs/debug.log';
104+
}
105+
100106
$this->debug_logger = new Logger('ck-debug');
101-
$stream_handler = new StreamHandler(__DIR__ . '/logs/debug.log', Logger::DEBUG);
107+
$stream_handler = new StreamHandler($debugLogFileLocation, Logger::DEBUG);
102108
$this->debug_logger->pushHandler(
103109
$stream_handler // phpcs:ignore Squiz.Objects.ObjectInstantiation.NotAssigned
104110
);
@@ -114,9 +120,25 @@ public function __construct(string $api_key, string $api_secret, bool $debug = f
114120
*/
115121
private function create_log(string $message)
116122
{
117-
if ($this->debug) {
118-
$this->debug_logger->info($message);
123+
// Don't log anything if debugging isn't enabled.
124+
if (!$this->debug) {
125+
return;
119126
}
127+
128+
// Mask the API Key and Secret.
129+
$message = str_replace(
130+
$this->api_key,
131+
str_repeat('*', (strlen($this->api_key) - 4)) . substr($this->api_key, - 4),
132+
$message
133+
);
134+
$message = str_replace(
135+
$this->api_secret,
136+
str_repeat('*', (strlen($this->api_secret) - 4)) . substr($this->api_secret, - 4),
137+
$message
138+
);
139+
140+
// Add to log.
141+
$this->debug_logger->info($message);
120142
}
121143

122144
/**

tests/ConvertKitAPITest.php

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,75 @@ public function testDebugEnabled()
6565
$this->assertStringContainsString('ck-debug.INFO: Finish request successfully', $this->getLogFileContents());
6666
}
6767

68+
/**
69+
* Test that debug logging works when enabled, a custom debug log file and path is specified
70+
* and an API call is made.
71+
*
72+
* @since 1.3.0
73+
*
74+
* @return void
75+
*/
76+
public function testDebugEnabledWithCustomLogFile()
77+
{
78+
// Define custom log file location.
79+
$this->logFile = dirname(dirname(__FILE__)) . '/src/logs/debug-custom.log';
80+
81+
// Setup API with debugging enabled.
82+
$api = new \ConvertKit_API\ConvertKit_API(
83+
$_ENV['CONVERTKIT_API_KEY'],
84+
$_ENV['CONVERTKIT_API_SECRET'],
85+
true,
86+
$this->logFile
87+
);
88+
$result = $api->get_account();
89+
90+
// Confirm log file exists.
91+
$this->assertFileExists($this->logFile);
92+
93+
// Confirm that the log includes expected data.
94+
$this->assertStringContainsString('ck-debug.INFO: GET account', $this->getLogFileContents());
95+
$this->assertStringContainsString('ck-debug.INFO: Finish request successfully', $this->getLogFileContents());
96+
}
97+
98+
/**
99+
* Test that debug logging works when enabled and an API call is made, with the API Key and Secret
100+
* masked in the log file.
101+
*
102+
* @since 1.3.0
103+
*
104+
* @return void
105+
*/
106+
public function testDebugAPIKeyAndSecretAreMasked()
107+
{
108+
// Setup API with debugging enabled.
109+
$api = new \ConvertKit_API\ConvertKit_API($_ENV['CONVERTKIT_API_KEY'], $_ENV['CONVERTKIT_API_SECRET'], true);
110+
111+
// Make requests that utilizes both the API Key and Secret.
112+
$api->get_forms(); // API Key.
113+
$api->get_account(); // API Secret.
114+
115+
// Define masked versions of API Key and Secret that we expect to see in the log file.
116+
$maskedAPIKey = str_replace(
117+
$_ENV['CONVERTKIT_API_KEY'],
118+
str_repeat('*', strlen($_ENV['CONVERTKIT_API_KEY']) - 4) . substr($_ENV['CONVERTKIT_API_KEY'], - 4),
119+
$_ENV['CONVERTKIT_API_KEY']
120+
);
121+
$maskedAPISecret = str_replace(
122+
$_ENV['CONVERTKIT_API_SECRET'],
123+
str_repeat('*', strlen($_ENV['CONVERTKIT_API_SECRET']) - 4) . substr($_ENV['CONVERTKIT_API_SECRET'], - 4),
124+
$_ENV['CONVERTKIT_API_SECRET']
125+
);
126+
127+
128+
// Confirm that the log includes the masked API Key and Secret.
129+
$this->assertStringContainsString($maskedAPIKey, $this->getLogFileContents());
130+
$this->assertStringContainsString($maskedAPISecret, $this->getLogFileContents());
131+
132+
// Confirm that the log does not include the unmasked API Key and Secret.
133+
$this->assertStringNotContainsString($_ENV['CONVERTKIT_API_KEY'], $this->getLogFileContents());
134+
$this->assertStringNotContainsString($_ENV['CONVERTKIT_API_SECRET'], $this->getLogFileContents());
135+
}
136+
68137
/**
69138
* Test that debug logging is not performed when disabled and an API call is made.
70139
*

0 commit comments

Comments
 (0)