diff --git a/composer.json b/composer.json index e2434ea..4885e0e 100644 --- a/composer.json +++ b/composer.json @@ -5,6 +5,11 @@ "support": { "email": "support@duosecurity.com" }, + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, "autoload": { "psr-4": { "DuoAPI\\": "src/" diff --git a/src/Client.php b/src/Client.php index 1579b07..81b5e6a 100644 --- a/src/Client.php +++ b/src/Client.php @@ -3,6 +3,7 @@ use DateTime; +const VERSION = "1.1.0-dev"; const INITIAL_BACKOFF_SECONDS = 1; const MAX_BACKOFF_SECONDS = 32; const BACKOFF_FACTOR = 2; @@ -159,6 +160,7 @@ public function apiCall($method, $path, $params) $headers = []; $headers["Date"] = $now; $headers["Host"] = $this->host; + $headers["User-Agent"] = "duo_api_php/" . VERSION; $headers["Authorization"] = self::signParameters( $method, $this->host, diff --git a/tests/Unit/ClientTest.php b/tests/Unit/ClientTest.php index c67eae0..1442220 100644 --- a/tests/Unit/ClientTest.php +++ b/tests/Unit/ClientTest.php @@ -317,4 +317,29 @@ public function testRateLimitedCompletely() 32 + ($this->random_numbers[5] / 1000), ], ($this->mock_sleep_svc->sleep_calls)); } + + public function testUserAgent() + { + $success_resp = [ + "success" => true, + "response" => "not rate limited", + "http_status_code" => 200, + ]; + + $response = [$success_resp]; + + $client = self::getMockedClient("Client", $response, $paged = true); + $this->mocked_curl_requester->method('execute')->with( + $this->anything(), + $this->anything(), + $this->callback(function($headers) { + $version = "duo_api_php/" . \DuoAPI\VERSION; + $this->assertArrayHasKey("User-Agent", $headers); + $this->assertEquals($headers["User-Agent"], $version); + return true; + }), + $this->anything() + ); + $response = $client->apiCall("GET", "/foo/bar", []); + } }