Skip to content

Commit eda6d82

Browse files
authored
Merge pull request #69 from ConvertKit/log-destination-and-masking
Define log location; mask API credentials
2 parents 415075b + 852a723 commit eda6d82

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
@@ -78,11 +78,12 @@ class ConvertKit_API
7878
/**
7979
* Constructor for ConvertKitAPI instance
8080
*
81-
* @param string $api_key ConvertKit API Key.
82-
* @param string $api_secret ConvertKit API Secret.
83-
* @param boolean $debug Log requests to debugger.
81+
* @param string $api_key ConvertKit API Key.
82+
* @param string $api_secret ConvertKit API Secret.
83+
* @param boolean $debug Log requests to debugger.
84+
* @param string $debugLogFileLocation Path and filename of debug file to write to.
8485
*/
85-
public function __construct(string $api_key, string $api_secret, bool $debug = false)
86+
public function __construct(string $api_key, string $api_secret, bool $debug = false, string $debugLogFileLocation = '')
8687
{
8788
$this->api_key = $api_key;
8889
$this->api_secret = $api_secret;
@@ -98,8 +99,13 @@ public function __construct(string $api_key, string $api_secret, bool $debug = f
9899
);
99100

100101
if ($debug) {
102+
// If no debug log file location specified, define a default.
103+
if (empty($debugLogFileLocation)) {
104+
$debugLogFileLocation = __DIR__ . '/logs/debug.log';
105+
}
106+
101107
$this->debug_logger = new Logger('ck-debug');
102-
$stream_handler = new StreamHandler(__DIR__ . '/logs/debug.log', Logger::DEBUG);
108+
$stream_handler = new StreamHandler($debugLogFileLocation, Logger::DEBUG);
103109
$this->debug_logger->pushHandler(
104110
$stream_handler // phpcs:ignore Squiz.Objects.ObjectInstantiation.NotAssigned
105111
);
@@ -129,9 +135,25 @@ public function set_http_client(ClientInterface $client)
129135
*/
130136
private function create_log(string $message)
131137
{
132-
if ($this->debug) {
133-
$this->debug_logger->info($message);
138+
// Don't log anything if debugging isn't enabled.
139+
if (!$this->debug) {
140+
return;
134141
}
142+
143+
// Mask the API Key and Secret.
144+
$message = str_replace(
145+
$this->api_key,
146+
str_repeat('*', (strlen($this->api_key) - 4)) . substr($this->api_key, - 4),
147+
$message
148+
);
149+
$message = str_replace(
150+
$this->api_secret,
151+
str_repeat('*', (strlen($this->api_secret) - 4)) . substr($this->api_secret, - 4),
152+
$message
153+
);
154+
155+
// Add to log.
156+
$this->debug_logger->info($message);
135157
}
136158

137159
/**

tests/ConvertKitAPITest.php

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

110+
/**
111+
* Test that debug logging works when enabled, a custom debug log file and path is specified
112+
* and an API call is made.
113+
*
114+
* @since 1.3.0
115+
*
116+
* @return void
117+
*/
118+
public function testDebugEnabledWithCustomLogFile()
119+
{
120+
// Define custom log file location.
121+
$this->logFile = dirname(dirname(__FILE__)) . '/src/logs/debug-custom.log';
122+
123+
// Setup API with debugging enabled.
124+
$api = new \ConvertKit_API\ConvertKit_API(
125+
$_ENV['CONVERTKIT_API_KEY'],
126+
$_ENV['CONVERTKIT_API_SECRET'],
127+
true,
128+
$this->logFile
129+
);
130+
$result = $api->get_account();
131+
132+
// Confirm log file exists.
133+
$this->assertFileExists($this->logFile);
134+
135+
// Confirm that the log includes expected data.
136+
$this->assertStringContainsString('ck-debug.INFO: GET account', $this->getLogFileContents());
137+
$this->assertStringContainsString('ck-debug.INFO: Finish request successfully', $this->getLogFileContents());
138+
}
139+
140+
/**
141+
* Test that debug logging works when enabled and an API call is made, with the API Key and Secret
142+
* masked in the log file.
143+
*
144+
* @since 1.3.0
145+
*
146+
* @return void
147+
*/
148+
public function testDebugAPIKeyAndSecretAreMasked()
149+
{
150+
// Setup API with debugging enabled.
151+
$api = new \ConvertKit_API\ConvertKit_API($_ENV['CONVERTKIT_API_KEY'], $_ENV['CONVERTKIT_API_SECRET'], true);
152+
153+
// Make requests that utilizes both the API Key and Secret.
154+
$api->get_forms(); // API Key.
155+
$api->get_account(); // API Secret.
156+
157+
// Define masked versions of API Key and Secret that we expect to see in the log file.
158+
$maskedAPIKey = str_replace(
159+
$_ENV['CONVERTKIT_API_KEY'],
160+
str_repeat('*', strlen($_ENV['CONVERTKIT_API_KEY']) - 4) . substr($_ENV['CONVERTKIT_API_KEY'], - 4),
161+
$_ENV['CONVERTKIT_API_KEY']
162+
);
163+
$maskedAPISecret = str_replace(
164+
$_ENV['CONVERTKIT_API_SECRET'],
165+
str_repeat('*', strlen($_ENV['CONVERTKIT_API_SECRET']) - 4) . substr($_ENV['CONVERTKIT_API_SECRET'], - 4),
166+
$_ENV['CONVERTKIT_API_SECRET']
167+
);
168+
169+
170+
// Confirm that the log includes the masked API Key and Secret.
171+
$this->assertStringContainsString($maskedAPIKey, $this->getLogFileContents());
172+
$this->assertStringContainsString($maskedAPISecret, $this->getLogFileContents());
173+
174+
// Confirm that the log does not include the unmasked API Key and Secret.
175+
$this->assertStringNotContainsString($_ENV['CONVERTKIT_API_KEY'], $this->getLogFileContents());
176+
$this->assertStringNotContainsString($_ENV['CONVERTKIT_API_SECRET'], $this->getLogFileContents());
177+
}
178+
110179
/**
111180
* Test that debug logging is not performed when disabled and an API call is made.
112181
*

0 commit comments

Comments
 (0)