From cc976dc069bbdb9fac3c2d02f6a60feb656c2138 Mon Sep 17 00:00:00 2001 From: Jesman Dzimba Date: Sun, 12 Mar 2023 15:49:55 +0200 Subject: [PATCH] Added basic auth verification (#2) Co-authored-by: jesmandzimba --- src/Clickatell/Common/Client.php | 99 ------------------- .../Exceptions/ValidationException.php | 8 ++ src/Clickatell/RequestValidator.php | 33 +++++++ src/Clickatell/SignedRequest.php | 57 +++++++++++ tests/MessageClientTest.php | 18 ++++ 5 files changed, 116 insertions(+), 99 deletions(-) delete mode 100644 src/Clickatell/Common/Client.php create mode 100644 src/Clickatell/Exceptions/ValidationException.php create mode 100644 src/Clickatell/RequestValidator.php create mode 100644 src/Clickatell/SignedRequest.php diff --git a/src/Clickatell/Common/Client.php b/src/Clickatell/Common/Client.php deleted file mode 100644 index 21d9d03..0000000 --- a/src/Clickatell/Common/Client.php +++ /dev/null @@ -1,99 +0,0 @@ -token = $token; - $this->options = $options; - - $this->headers = [ - 'Accept: application/json', - 'Authorization: '.$this->token, - 'Content-Type: application/json', - ]; - $this->timeout = 120; - $this->connectionTimeout = 120; - } - - public function setTimeout(int $timeout): void - { - $this->timeout = $timeout; - } - - public function setConnectionTimeout(int $connectionTimeout): void - { - $this->connectionTimeout = $connectionTimeout; - } - - public function setHeaders(array $headers): void - { - array_merge($this->headers, $headers); - } - - public function getHeaders(): array - { - return $this->headers; - } - - public function get(string $endpoint) - { - return $this->request($endpoint); - } - - public function post(string $endpoint, string $data) - { - return $this->request($endpoint, 'post', $data); - } - - public function request($endpoint, $type='get', $data=null) - { - switch($type) - { - case 'post': - $options = [ - CURLOPT_POST => true, - CURLOPT_POSTFIELDS => $data, - ]; - break; - default: - $options = []; - } - - $defaults = array_merge([ - CURLOPT_HEADER => false, - CURLOPT_HTTPHEADER => $this->headers, - CURLOPT_CONNECTTIMEOUT => $this->connectionTimeout, - CURLOPT_TIMEOUT => $this->timeout, - CURLOPT_RETURNTRANSFER => true - ], $options); - - $this->connect($endpoint); - curl_setopt_array($this->session, ($this->options + $defaults)); - $response = json_decode(curl_exec($this->session)); - $statusCode = curl_getinfo($this->session, CURLINFO_HTTP_CODE); - $this->disconnect(); - return new Response($statusCode, $response); - } - - - private function connect(string $endpoint) - { - $this->session = curl_init($endpoint); - } - - private function disconnect() - { - return curl_close($this->session); - } -} diff --git a/src/Clickatell/Exceptions/ValidationException.php b/src/Clickatell/Exceptions/ValidationException.php new file mode 100644 index 0000000..c767b9b --- /dev/null +++ b/src/Clickatell/Exceptions/ValidationException.php @@ -0,0 +1,8 @@ +signingUsername = $signingUsername; + $this->signingPassword = $signingPassword; + } + + /** + * Verify the request is from someone authenticated + */ + public function verify(SignedRequest $signedRequest): bool + { + if( $this->signingUsername !== $signedRequest->username || + $this->signingPassword !== $signedRequest->password + ) { + return false; + } + return true; + } +} \ No newline at end of file diff --git a/src/Clickatell/SignedRequest.php b/src/Clickatell/SignedRequest.php new file mode 100644 index 0000000..3a8464f --- /dev/null +++ b/src/Clickatell/SignedRequest.php @@ -0,0 +1,57 @@ +validateRequest($requestData); + $signedRequest->setPropertyValues((object) $requestData); + } catch(ValidationException $ex) { + throw new ValidationException($ex->getMessage()); + } + return $signedRequest; + } + + public function setPropertyValues(stdClass $object): self + { + foreach($object as $key => $value) { + if (property_exists($this, $key)) { + $this->$key = $value; + } + } + return $this; + } + + /** + * @throws ValidationException + */ + private function validateRequest(array $request): void + { + $required = [ + 'username' => 'is_string', + 'password'=> 'is_string' + ]; + foreach($required as $name => $type) { + if (!isset($request[$name])) { + throw new ValidationException($name.' is required.'); + } + + if (! $type($request[$name])) { + throw new ValidationException($name.' is invalid.'); + } + } + } +} \ No newline at end of file diff --git a/tests/MessageClientTest.php b/tests/MessageClientTest.php index fc90d73..5651eb9 100755 --- a/tests/MessageClientTest.php +++ b/tests/MessageClientTest.php @@ -7,6 +7,8 @@ use PHPUnit\Framework\TestCase; use Clickatell\Client; use Clickatell\Models\Messages\Sms; +use Clickatell\SignedRequest; +use Clickatell\RequestValidator; class MessageClientTest extends TestCase @@ -18,6 +20,22 @@ public function testSendingMessage(): void $this->assertTrue($res->success()); } + public function testSignedRequest(): void + { + $username = 'signedSignature'; + $password = '234234'; + $signedRequest = SignedRequest::create($username, $password); + $this->assertEquals($username, $signedRequest->username); + $this->assertEquals($password, $signedRequest->password); + } + + public function testRequestValidation() + { + $validator = new RequestValidator('jane', 'janedoe'); + $signedRequest = SignedRequest::create('jane', 'janedoe'); + $this->assertTrue($validator->verify($signedRequest)); + } + private function createSms(): Sms { return new Sms('your_test_mobile', 'Base sent from unit tests @ '.time(), 'your_test_from');