Vendoring deprecated composer libs

This commit is contained in:
Frédéric Guillot 2018-06-21 14:13:41 -07:00
parent c73ac5f1f8
commit a491348d44
515 changed files with 5376 additions and 693 deletions

View File

@ -29,16 +29,13 @@
"christian-riesen/otp" : "1.4.3",
"eluceo/ical": "0.10.1",
"erusev/parsedown" : "1.7.1",
"fguillot/json-rpc" : "1.2.1",
"fguillot/picodb" : "v1.0.18",
"paragonie/random_compat": "2.0.11",
"pimple/pimple" : "3.2.2",
"psr/log": "~1.0",
"swiftmailer/swiftmailer" : "5.4.8",
"symfony/console" : "3.4.2",
"symfony/event-dispatcher" : "3.4.2",
"gregwar/captcha": "1.1.4",
"aferrandini/phpqrcode": "1.0.1"
"gregwar/captcha": "1.1.4"
},
"autoload" : {
"classmap" : ["app/"],
@ -59,7 +56,9 @@
"phpdocumentor/reflection-docblock": "3.3.2",
"symfony/debug": "3.4.2",
"symfony/yaml": "3.4.2",
"symfony/finder": "3.4.8",
"symfony/stopwatch" : "3.4.2",
"myclabs/deep-copy": "1.7.0",
"phpunit/phpunit" : "5.7.24",
"phpunit/phpunit-selenium": "3.0.3"
}

138
composer.lock generated
View File

@ -4,53 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "6bb506d8bbacef8a6eb542c564c5a3ab",
"content-hash": "c4e8b7c267db97b532117fc9bc88c917",
"packages": [
{
"name": "aferrandini/phpqrcode",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/aferrandini/PHPQRCode.git",
"reference": "3c1c0454d43710ab5bbe19a51ad4cb41c22e3d46"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/aferrandini/PHPQRCode/zipball/3c1c0454d43710ab5bbe19a51ad4cb41c22e3d46",
"reference": "3c1c0454d43710ab5bbe19a51ad4cb41c22e3d46",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"autoload": {
"psr-0": {
"PHPQRCode": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ariel Ferrandini",
"email": "arielferrandini@gmail.com",
"homepage": "http://www.ferrandini.com/",
"role": "Developer"
}
],
"description": "PHPQRCode porting and changed for PHP 5.3 compatibility",
"homepage": "https://github.com/aferrandini/PHPQRCode",
"keywords": [
"barcode",
"php",
"qrcode"
],
"abandoned": "endroid/qr-code",
"time": "2013-07-08T09:39:08+00:00"
},
{
"name": "christian-riesen/base32",
"version": "1.3.1",
@ -255,85 +210,6 @@
],
"time": "2018-03-08T01:11:30+00:00"
},
{
"name": "fguillot/json-rpc",
"version": "v1.2.1",
"source": {
"type": "git",
"url": "https://github.com/fguillot/JsonRPC.git",
"reference": "d491bb549bfa11aff4c37abcea2ffb28c9523f69"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/fguillot/JsonRPC/zipball/d491bb549bfa11aff4c37abcea2ffb28c9523f69",
"reference": "d491bb549bfa11aff4c37abcea2ffb28c9523f69",
"shasum": ""
},
"require": {
"php": ">=5.3.4"
},
"require-dev": {
"phpunit/phpunit": "4.8.*"
},
"type": "library",
"autoload": {
"psr-0": {
"JsonRPC": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Frédéric Guillot"
}
],
"description": "Simple Json-RPC client/server library that just works",
"homepage": "https://github.com/fguillot/JsonRPC",
"time": "2016-06-25T23:11:10+00:00"
},
{
"name": "fguillot/picodb",
"version": "v1.0.18",
"source": {
"type": "git",
"url": "https://github.com/fguillot/picoDb.git",
"reference": "4df08a3cc3c4a39e6bb329872f5d020fe135f805"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/fguillot/picoDb/zipball/4df08a3cc3c4a39e6bb329872f5d020fe135f805",
"reference": "4df08a3cc3c4a39e6bb329872f5d020fe135f805",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"phpunit/phpunit": "4.8.*"
},
"type": "library",
"autoload": {
"psr-0": {
"PicoDb": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Frédéric Guillot",
"homepage": "https://github.com/fguillot/"
}
],
"description": "Minimalist database query builder",
"homepage": "https://github.com/fguillot/picoDb",
"time": "2018-03-05T22:39:16+00:00"
},
{
"name": "gregwar/captcha",
"version": "v1.1.4",
@ -874,16 +750,16 @@
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.7.0",
"version": "v1.8.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b"
"reference": "3296adf6a6454a050679cde90f95350ad604b171"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/78be803ce01e55d3491c1397cf1c64beb9c1b63b",
"reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/3296adf6a6454a050679cde90f95350ad604b171",
"reference": "3296adf6a6454a050679cde90f95350ad604b171",
"shasum": ""
},
"require": {
@ -895,7 +771,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.7-dev"
"dev-master": "1.8-dev"
}
},
"autoload": {
@ -929,7 +805,7 @@
"portable",
"shim"
],
"time": "2018-01-30T19:27:44+00:00"
"time": "2018-04-26T10:06:28+00:00"
}
],
"packages-dev": [

View File

@ -0,0 +1,412 @@
JsonRPC PHP Client and Server
=============================
A simple Json-RPC client/server that just works.
Features
--------
- JSON-RPC 2.0 only
- The server support batch requests and notifications
- Authentication and IP based client restrictions
- Custom Middleware
- Fully unit tested
- Requirements: PHP >= 5.3.4
- License: MIT
Author
------
Frédéric Guillot
Installation with Composer
--------------------------
```bash
composer require fguillot/json-rpc @stable
```
Examples
--------
### Server
Callback binding:
```php
<?php
use JsonRPC\Server;
$server = new Server();
$server->getProcedureHandler()
->withCallback('addition', function ($a, $b) {
return $a + $b;
})
->withCallback('random', function ($start, $end) {
return mt_rand($start, $end);
})
;
echo $server->execute();
```
Callback binding from array:
```php
<?php
use JsonRPC\Server;
$callbacks = array(
'getA' => function() { return 'A'; },
'getB' => function() { return 'B'; },
'getC' => function() { return 'C'; }
);
$server = new Server();
$server->getProcedureHandler()->withCallbackArray($callbacks);
echo $server->execute();
```
Class/Method binding:
```php
<?php
use JsonRPC\Server;
class Api
{
public function doSomething($arg1, $arg2 = 3)
{
return $arg1 + $arg2;
}
}
$server = new Server();
$procedureHandler = $server->getProcedureHandler();
// Bind the method Api::doSomething() to the procedure myProcedure
$procedureHandler->withClassAndMethod('myProcedure', 'Api', 'doSomething');
// Use a class instance instead of the class name
$procedureHandler->withClassAndMethod('mySecondProcedure', new Api, 'doSomething');
// The procedure and the method are the same
$procedureHandler->withClassAndMethod('doSomething', 'Api');
// Attach the class, the client will be able to call directly Api::doSomething()
$procedureHandler->withObject(new Api());
echo $server->execute();
```
Class/Method binding from array:
```php
<?php
use JsonRPC\Server;
class MathApi
{
public function addition($arg1, $arg2)
{
return $arg1 + $arg2;
}
public function subtraction($arg1, $arg2)
{
return $arg1 - $arg2;
}
public function multiplication($arg1, $arg2)
{
return $arg1 * $arg2;
}
public function division($arg1, $arg2)
{
return $arg1 / $arg2;
}
}
$callbacks = array(
'addition' => array( 'MathApi', addition ),
'subtraction' => array( 'MathApi', subtraction ),
'multiplication' => array( 'MathApi', multiplication ),
'division' => array( 'MathApi', division )
);
$server = new Server();
$server->getProcedureHandler()->withClassAndMethodArray($callbacks);
echo $server->execute();
```
Server Middleware:
Middleware might be used to authenticate and authorize the client.
They are executed before each procedure.
```php
<?php
use JsonRPC\Server;
use JsonRPC\MiddlewareInterface;
use JsonRPC\Exception\AuthenticationFailureException;
class Api
{
public function doSomething($arg1, $arg2 = 3)
{
return $arg1 + $arg2;
}
}
class MyMiddleware implements MiddlewareInterface
{
public function execute($username, $password, $procedureName)
{
if ($username !== 'foobar') {
throw new AuthenticationFailureException('Wrong credentials!');
}
}
}
$server = new Server();
$server->getMiddlewareHandler()->withMiddleware(new MyMiddleware());
$server->getProcedureHandler()->withObject(new Api());
echo $server->execute();
```
You can raise a `AuthenticationFailureException` when the API credentials are wrong or a `AccessDeniedException` when the user is not allowed to access to the procedure.
### Client
Example with positional parameters:
```php
<?php
use JsonRPC\Client;
$client = new Client('http://localhost/server.php');
$result = $client->execute('addition', [3, 5]);
```
Example with named arguments:
```php
<?php
use JsonRPC\Client;
$client = new Client('http://localhost/server.php');
$result = $client->execute('random', ['end' => 10, 'start' => 1]);
```
Arguments are called in the right order.
Examples with the magic method `__call()`:
```php
<?php
use JsonRPC\Client;
$client = new Client('http://localhost/server.php');
$result = $client->random(50, 100);
```
The example above use positional arguments for the request and this one use named arguments:
```php
$result = $client->random(['end' => 10, 'start' => 1]);
```
### Client batch requests
Call several procedures in a single HTTP request:
```php
<?php
use JsonRPC\Client;
$client = new Client('http://localhost/server.php');
$results = $client->batch()
->foo(['arg1' => 'bar'])
->random(1, 100)
->add(4, 3)
->execute('add', [2, 5])
->send();
print_r($results);
```
All results are stored at the same position of the call.
### Client exceptions
Client exceptions are normally thrown when an error is returned by the server. You can change this behaviour by
using the `$returnException` argument which causes exceptions to be returned. This can be extremely useful when
executing the batch request.
- `BadFunctionCallException`: Procedure not found on the server
- `InvalidArgumentException`: Wrong procedure arguments
- `JsonRPC\Exception\AccessDeniedException`: Access denied
- `JsonRPC\Exception\ConnectionFailureException`: Connection failure
- `JsonRPC\Exception\ServerErrorException`: Internal server error
### Enable client debugging
You can enable the debug mode to see the JSON request and response:
```php
<?php
use JsonRPC\Client;
$client = new Client('http://localhost/server.php');
$client->getHttpClient()->withDebug();
```
The debug output is sent to the PHP system logger.
You can configure the log destination in your `php.ini`.
Output example:
```json
==> Request:
{
"jsonrpc": "2.0",
"method": "removeCategory",
"id": 486782327,
"params": [
1
]
}
==> Response:
{
"jsonrpc": "2.0",
"id": 486782327,
"result": true
}
```
### IP based client restrictions
The server can allow only some IP addresses:
```php
<?php
use JsonRPC\Server;
$server = new Server;
// IP client restrictions
$server->allowHosts(['192.168.0.1', '127.0.0.1']);
[...]
// Return the response to the client
echo $server->execute();
```
If the client is blocked, you got a 403 Forbidden HTTP response.
### HTTP Basic Authentication
If you use HTTPS, you can allow client by using a username/password.
```php
<?php
use JsonRPC\Server;
$server = new Server;
// List of users to allow
$server->authentication(['user1' => 'password1', 'user2' => 'password2']);
[...]
// Return the response to the client
echo $server->execute();
```
On the client, set credentials like that:
```php
<?php
use JsonRPC\Client;
$client = new Client('http://localhost/server.php');
$client->getHttpClient()
->withUsername('Foo')
->withPassword('Bar');
```
If the authentication failed, the client throw a RuntimeException.
Using an alternative authentication header:
```php
use JsonRPC\Server;
$server = new Server();
$server->setAuthenticationHeader('X-Authentication');
$server->authentication(['myusername' => 'mypassword']);
```
The example above will use the HTTP header `X-Authentication` instead of the standard `Authorization: Basic [BASE64_CREDENTIALS]`.
The username/password values need be encoded in base64: `base64_encode('username:password')`.
### Local Exceptions
By default, the server will relay all exceptions to the client.
If you would like to relay only some of them, use the method `Server::withLocalException($exception)`:
```php
<?php
use JsonRPC\Server;
class MyException1 extends Exception {};
class MyException2 extends Exception {};
$server = new Server();
// Exceptions that should NOT be relayed to the client, if they occurs
$server
->withLocalException('MyException1')
->withLocalException('MyException2')
;
[...]
echo $server->execute();
```
### Callback before client request
You can use a callback to change the HTTP headers or the URL before to make the request to the server.
Example:
```php
<?php
$client = new Client();
$client->getHttpClient()->withBeforeRequestCallback(function(HttpClient $client, $payload) {
$client->withHeaders(array('Content-Length: '.strlen($payload)));
});
$client->myProcedure(123);
```

View File

@ -158,14 +158,17 @@ class Client
* @param string $procedure Procedure name
* @param array $params Procedure arguments
* @param array $reqattrs
* @param string|null $requestId Request Id
* @param string[] $headers Headers for this request
* @return mixed
*/
public function execute($procedure, array $params = array(), array $reqattrs = array())
public function execute($procedure, array $params = array(), array $reqattrs = array(), $requestId = null, array $headers = array())
{
$payload = RequestBuilder::create()
->withProcedure($procedure)
->withParams($params)
->withRequestAttributes($reqattrs)
->withId($requestId)
->build();
if ($this->isBatch) {
@ -173,7 +176,7 @@ class Client
return $this;
}
return $this->sendPayload($payload);
return $this->sendPayload($payload, $headers);
}
/**
@ -182,13 +185,14 @@ class Client
* @access private
* @throws Exception
* @param string $payload
* @param string[] $headers
* @return Exception|Client
*/
private function sendPayload($payload)
private function sendPayload($payload, array $headers = array())
{
return ResponseParser::create()
->withReturnException($this->returnException)
->withPayload($this->httpClient->execute($payload))
->withPayload($this->httpClient->execute($payload, $headers))
->parse();
}
}

View File

@ -2,14 +2,12 @@
namespace JsonRPC\Exception;
use Exception;
/**
* Class AccessDeniedException
*
* @package JsonRPC\Exception
* @author Frederic Guillot
*/
class AccessDeniedException extends Exception
class AccessDeniedException extends RpcCallFailedException
{
}

View File

@ -2,14 +2,12 @@
namespace JsonRPC\Exception;
use Exception;
/**
* Class AuthenticationFailureException
*
* @package JsonRPC\Exception
* @author Frederic Guillot
*/
class AuthenticationFailureException extends Exception
class AuthenticationFailureException extends RpcCallFailedException
{
}

View File

@ -2,14 +2,12 @@
namespace JsonRPC\Exception;
use Exception;
/**
* Class ConnectionFailureException
*
* @package JsonRPC\Exception
* @author Frederic Guillot
*/
class ConnectionFailureException extends Exception
class ConnectionFailureException extends RpcCallFailedException
{
}

View File

@ -2,14 +2,12 @@
namespace JsonRPC\Exception;
use Exception;
/**
* Class InvalidJsonFormatException
*
* @package JsonRPC\Exception
* @author Frederic Guillot
*/
class InvalidJsonFormatException extends Exception
class InvalidJsonFormatException extends RpcCallFailedException
{
}

View File

@ -2,14 +2,12 @@
namespace JsonRPC\Exception;
use Exception;
/**
* Class InvalidJsonRpcFormatException
*
* @package JsonRPC\Exception
* @author Frederic Guillot
*/
class InvalidJsonRpcFormatException extends Exception
class InvalidJsonRpcFormatException extends RpcCallFailedException
{
}

View File

@ -2,14 +2,12 @@
namespace JsonRPC\Exception;
use Exception;
/**
* Class ResponseEncodingFailureException
*
* @package JsonRPC\Exception
* @author Frederic Guillot
*/
class ResponseEncodingFailureException extends Exception
class ResponseEncodingFailureException extends RpcCallFailedException
{
}

View File

@ -10,7 +10,7 @@ use Exception;
* @package JsonRPC\Exception
* @author Frederic Guillot
*/
class ResponseException extends Exception
class ResponseException extends RpcCallFailedException
{
/**
* A value that contains additional information about the error.

View File

@ -0,0 +1,15 @@
<?php
namespace JsonRPC\Exception;
use Exception;
/**
* Class RpcCallFailedException
*
* @package JsonRPC\Exception
* @author Frederic Guillot
*/
class RpcCallFailedException extends Exception
{
}

View File

@ -2,14 +2,12 @@
namespace JsonRPC\Exception;
use Exception;
/**
* Class ServerErrorException
*
* @package JsonRPC\Exception
* @author Frederic Guillot
*/
class ServerErrorException extends Exception
class ServerErrorException extends RpcCallFailedException
{
}

View File

@ -18,26 +18,26 @@ class HttpClient
/**
* URL of the server
*
* @access private
* @access protected
* @var string
*/
private $url;
protected $url;
/**
* HTTP client timeout
*
* @access private
* @access protected
* @var integer
*/
private $timeout = 5;
protected $timeout = 5;
/**
* Default HTTP headers to send to the server
*
* @access private
* @access protected
* @var array
*/
private $headers = array(
protected $headers = array(
'User-Agent: JSON-RPC PHP Client <https://github.com/fguillot/JsonRPC>',
'Content-Type: application/json',
'Accept: application/json',
@ -47,50 +47,58 @@ class HttpClient
/**
* Username for authentication
*
* @access private
* @access protected
* @var string
*/
private $username;
protected $username;
/**
* Password for authentication
*
* @access private
* @access protected
* @var string
*/
private $password;
protected $password;
/**
* Enable debug output to the php error log
*
* @access private
* @access protected
* @var boolean
*/
private $debug = false;
protected $debug = false;
/**
* Cookies
*
* @access private
* @access protected
* @var array
*/
private $cookies = array();
protected $cookies = array();
/**
* SSL certificates verification
*
* @access private
* @access protected
* @var boolean
*/
private $verifySslCertificate = true;
protected $verifySslCertificate = true;
/**
* SSL client certificate
*
* @access protected
* @var string
*/
protected $sslLocalCert;
/**
* Callback called before the doing the request
*
* @access private
* @access protected
* @var Closure
*/
private $beforeRequest;
protected $beforeRequest;
/**
* HttpClient constructor
@ -156,7 +164,7 @@ class HttpClient
}
/**
* Set timeout
* Set headers
*
* @access public
* @param array $headers
@ -208,6 +216,18 @@ class HttpClient
return $this;
}
/**
* Assign a certificate to use TLS
*
* @access public
* @return $this
*/
public function withSslLocalCert($path)
{
$this->sslLocalCert = $path;
return $this;
}
/**
* Assign a callback before the request
*
@ -238,15 +258,45 @@ class HttpClient
* @access public
* @throws ConnectionFailureException
* @param string $payload
* @param string[] $headers Headers for this request
* @return array
*/
public function execute($payload)
public function execute($payload, array $headers = array())
{
if (is_callable($this->beforeRequest)) {
call_user_func_array($this->beforeRequest, array($this, $payload));
call_user_func_array($this->beforeRequest, array($this, $payload, $headers));
}
$stream = fopen(trim($this->url), 'r', false, $this->buildContext($payload));
if ($this->isCurlLoaded()) {
$ch = curl_init();
$requestHeaders = $this->buildHeaders($headers);
$headers = array();
curl_setopt_array($ch, array(
CURLOPT_URL => trim($this->url),
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => $this->timeout,
CURLOPT_MAXREDIRS => 2,
CURLOPT_SSL_VERIFYPEER => $this->verifySslCertificate,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => $requestHeaders,
CURLOPT_HEADERFUNCTION => function ($curl, $header) use (&$headers) {
$headers[] = $header;
return strlen($header);
}
));
if ($this->sslLocalCert !== null) {
curl_setopt($ch, CURLOPT_CAINFO, $this->sslLocalCert);
}
$response = curl_exec($ch);
curl_close($ch);
if ($response !== false) {
$response = json_decode($response, true);
} else {
throw new ConnectionFailureException('Unable to establish a connection');
}
} else {
$stream = fopen(trim($this->url), 'r', false, $this->buildContext($payload, $headers));
if (! is_resource($stream)) {
throw new ConnectionFailureException('Unable to establish a connection');
@ -256,6 +306,9 @@ class HttpClient
$headers = $metadata['wrapper_data'];
$response = json_decode(stream_get_contents($stream), true);
fclose($stream);
}
if ($this->debug) {
error_log('==> Request: '.PHP_EOL.(is_string($payload) ? $payload : json_encode($payload, JSON_PRETTY_PRINT)));
error_log('==> Headers: '.PHP_EOL.var_export($headers, true));
@ -271,29 +324,16 @@ class HttpClient
/**
* Prepare stream context
*
* @access private
* @access protected
* @param string $payload
* @param string[] $headers
* @return resource
*/
private function buildContext($payload)
protected function buildContext($payload, array $headers = array())
{
$headers = $this->headers;
$headers = $this->buildHeaders($headers);
if (! empty($this->username) && ! empty($this->password)) {
$headers[] = 'Authorization: Basic '.base64_encode($this->username.':'.$this->password);
}
if (! empty($this->cookies)){
$cookies = array();
foreach ($this->cookies as $key => $value) {
$cookies[] = $key.'='.$value;
}
$headers[] = 'Cookie: '.implode('; ', $cookies);
}
return stream_context_create(array(
$options = array(
'http' => array(
'method' => 'POST',
'protocol_version' => 1.1,
@ -307,16 +347,22 @@ class HttpClient
'verify_peer' => $this->verifySslCertificate,
'verify_peer_name' => $this->verifySslCertificate,
)
));
);
if ($this->sslLocalCert !== null) {
$options['ssl']['local_cert'] = $this->sslLocalCert;
}
return stream_context_create($options);
}
/**
* Parse cookies from response
*
* @access private
* @access protected
* @param array $headers
*/
private function parseCookies(array $headers)
protected function parseCookies(array $headers)
{
foreach ($headers as $header) {
$pos = stripos($header, 'Set-Cookie:');
@ -362,4 +408,42 @@ class HttpClient
}
}
}
/**
* Tests if the curl extension is loaded
*
* @access protected
* @return bool
*/
protected function isCurlLoaded()
{
return extension_loaded('curl');
}
/**
* Prepare Headers
*
* @access protected
* @param array $headers
* @return array
*/
protected function buildHeaders(array $headers)
{
$headers = array_merge($this->headers, $headers);
if (!empty($this->username) && !empty($this->password)) {
$headers[] = 'Authorization: Basic ' . base64_encode($this->username . ':' . $this->password);
}
if (!empty($this->cookies)) {
$cookies = array();
foreach ($this->cookies as $key => $value) {
$cookies[] = $key . '=' . $value;
}
$headers[] = 'Cookie: ' . implode('; ', $cookies);
}
return $headers;
}
}

View File

@ -107,6 +107,38 @@ class ProcedureHandler
return $this;
}
/**
* Register multiple procedures from array
*
* @access public
* @param array $callbacks Array with procedure names (array keys) and callbacks (array values)
* @return $this
*/
public function withCallbackArray($callbacks)
{
foreach ($callbacks as $procedure => $callback) {
$this->withCallback($procedure, $callback);
}
return $this;
}
/**
* Bind multiple procedures to classes from array
*
* @access public
* @param array $callbacks Array with procedure names (array keys) and class and method names (array values)
* @return $this
*/
public function withClassAndMethodArray($callbacks)
{
foreach ($callbacks as $procedure => $callback) {
$this->withClassAndMethod($procedure, $callback[0], $callback[1]);
}
return $this;
}
/**
* Execute the procedure
*
@ -250,7 +282,7 @@ class ProcedureHandler
foreach ($methodParams as $p) {
$name = $p->getName();
if (isset($requestParams[$name])) {
if (array_key_exists($name, $requestParams)) {
$params[$name] = $requestParams[$name];
} elseif ($p->isDefaultValueAvailable()) {
$params[$name] = $p->getDefaultValue();

View File

@ -24,26 +24,26 @@ class ResponseBuilder
/**
* Payload ID
*
* @access private
* @access protected
* @var mixed
*/
private $id;
protected $id;
/**
* Payload ID
*
* @access private
* @access protected
* @var mixed
*/
private $result;
protected $result;
/**
* Payload error code
*
* @access private
* @access protected
* @var integer
*/
private $errorCode;
protected $errorCode;
/**
* Payload error message
@ -51,41 +51,41 @@ class ResponseBuilder
* @access private
* @var string
*/
private $errorMessage;
protected $errorMessage;
/**
* Payload error data
*
* @access private
* @access protected
* @var mixed
*/
private $errorData;
protected $errorData;
/**
* HTTP Headers
*
* @access private
* @access protected
* @var array
*/
private $headers = array(
protected $headers = array(
'Content-Type' => 'application/json',
);
/**
* HTTP status
*
* @access private
* @access protected
* @var string
*/
private $status;
protected $status;
/**
* Exception
*
* @access private
* @access protected
* @var ResponseException
*/
private $exception;
protected $exception;
/**
* Get new object instance
@ -212,7 +212,14 @@ class ResponseBuilder
*/
public function build()
{
$encodedResponse = json_encode($this->buildResponse());
$options = 0;
if (defined('JSON_UNESCAPED_SLASHES')) {
$options |= JSON_UNESCAPED_SLASHES;
}
if (defined('JSON_UNESCAPED_UNICODE')) {
$options |= JSON_UNESCAPED_UNICODE;
}
$encodedResponse = json_encode($this->buildResponse(), $options);
JsonEncodingValidator::validate();
return $encodedResponse;
@ -240,10 +247,10 @@ class ResponseBuilder
/**
* Build response payload
*
* @access private
* @access protected
* @return array
*/
private function buildResponse()
protected function buildResponse()
{
$response = array('jsonrpc' => '2.0');
$this->handleExceptions();
@ -261,10 +268,10 @@ class ResponseBuilder
/**
* Build response error payload
*
* @access private
* @access protected
* @return array
*/
private function buildErrorResponse()
protected function buildErrorResponse()
{
$response = array(
'code' => $this->errorCode,
@ -281,42 +288,47 @@ class ResponseBuilder
/**
* Transform exceptions to JSON-RPC errors
*
* @access private
* @access protected
*/
private function handleExceptions()
protected function handleExceptions()
{
if ($this->exception instanceof InvalidJsonFormatException) {
try {
if ($this->exception instanceof Exception) {
throw $this->exception;
}
} catch (InvalidJsonFormatException $e) {
$this->errorCode = -32700;
$this->errorMessage = 'Parse error';
$this->id = null;
} elseif ($this->exception instanceof InvalidJsonRpcFormatException) {
} catch (InvalidJsonRpcFormatException $e) {
$this->errorCode = -32600;
$this->errorMessage = 'Invalid Request';
$this->id = null;
} elseif ($this->exception instanceof BadFunctionCallException) {
} catch (BadFunctionCallException $e) {
$this->errorCode = -32601;
$this->errorMessage = 'Method not found';
} elseif ($this->exception instanceof InvalidArgumentException) {
} catch (InvalidArgumentException $e) {
$this->errorCode = -32602;
$this->errorMessage = 'Invalid params';
} elseif ($this->exception instanceof ResponseEncodingFailureException) {
$this->errorData = $this->exception->getMessage();
} catch (ResponseEncodingFailureException $e) {
$this->errorCode = -32603;
$this->errorMessage = 'Internal error';
$this->errorData = $this->exception->getMessage();
} elseif ($this->exception instanceof AuthenticationFailureException) {
} catch (AuthenticationFailureException $e) {
$this->errorCode = 401;
$this->errorMessage = 'Unauthorized';
$this->status = 'HTTP/1.0 401 Unauthorized';
$this->withHeader('WWW-Authenticate', 'Basic realm="JsonRPC"');
} elseif ($this->exception instanceof AccessDeniedException) {
} catch (AccessDeniedException $e) {
$this->errorCode = 403;
$this->errorMessage = 'Forbidden';
$this->status = 'HTTP/1.0 403 Forbidden';
} elseif ($this->exception instanceof ResponseException) {
} catch (ResponseException $e) {
$this->errorCode = $this->exception->getCode();
$this->errorMessage = $this->exception->getMessage();
$this->errorData = $this->exception->getData();
} elseif ($this->exception instanceof Exception) {
} catch (Exception $e) {
$this->errorCode = $this->exception->getCode();
$this->errorMessage = $this->exception->getMessage();
}

View File

@ -0,0 +1,73 @@
<?php
namespace JsonRPC\Validator;
use JsonRPC\Exception\AccessDeniedException;
/**
* Class HostValidator
*
* @package JsonRPC\Validator
* @author Frederic Guillot
*/
class HostValidator
{
/**
* Validate
*
* @static
* @access public
* @param array $hosts
* @param string $remoteAddress
* @throws AccessDeniedException
*/
public static function validate(array $hosts, $remoteAddress)
{
if (!empty($hosts)) {
foreach ($hosts as $host) {
if (self::ipMatch($remoteAddress, $host)) {
return;
}
}
throw new AccessDeniedException('Access Forbidden');
}
}
/**
* Validate remoteAddress match host
* @param $remoteAddress
* @param $host
* @return bool
*/
public static function ipMatch($remoteAddress, $host)
{
$host = trim($host);
if (strpos($host, '/') !== false) {
list($network, $mask) = explode('/', $host);
if (self::netMatch($remoteAddress, $network, $mask)) {
return true;
}
}
if ($host === $remoteAddress) {
return true;
}
return false;
}
/**
* validate the ipAddress in network
* 192.168.1.1/24
* @param $clientIp
* @param $networkIp
* @param $mask
*
* @return bool
*/
public static function netMatch($clientIp, $networkIp, $mask)
{
$mask1 = 32 - $mask;
return ((ip2long($clientIp) >> $mask1) == (ip2long($networkIp) >> $mask1));
}
}

View File

@ -0,0 +1,103 @@
<?php
use JsonRPC\Client;
require_once __DIR__.'/../../../vendor/autoload.php';
class ClientTest extends PHPUnit_Framework_TestCase
{
private $httpClient;
public function setUp()
{
$this->httpClient = $this
->getMockBuilder('\JsonRPC\HttpClient')
->setMethods(array('execute'))
->getMock();
}
public function testSendBatch()
{
$client = new Client('', false, $this->httpClient);
$response = array(
array(
'jsonrpc' => '2.0',
'result' => 'c',
'id' => 1,
),
array(
'jsonrpc' => '2.0',
'result' => 'd',
'id' => 2,
)
);
$this->httpClient
->expects($this->once())
->method('execute')
->with($this->stringContains('[{"jsonrpc":"2.0","method":"methodA","id":'))
->will($this->returnValue($response));
$result = $client->batch()
->execute('methodA', array('a' => 'b'))
->execute('methodB', array('a' => 'b'))
->send();
$this->assertEquals(array('c', 'd'), $result);
}
public function testSendRequest()
{
$client = new Client('', false, $this->httpClient);
$this->httpClient
->expects($this->once())
->method('execute')
->with($this->stringContains('{"jsonrpc":"2.0","method":"methodA","id":'))
->will($this->returnValue(array('jsonrpc' => '2.0', 'result' => 'foobar', 'id' => 1)));
$result = $client->execute('methodA', array('a' => 'b'));
$this->assertEquals($result, 'foobar');
}
public function testSendRequestWithError()
{
$client = new Client('', false, $this->httpClient);
$this->httpClient
->expects($this->once())
->method('execute')
->with($this->stringContains('{"jsonrpc":"2.0","method":"methodA","id":'))
->will($this->returnValue(array(
'jsonrpc' => '2.0',
'error' => array(
'code' => -32601,
'message' => 'Method not found',
),
)));
$this->setExpectedException('BadFunctionCallException');
$client->execute('methodA', array('a' => 'b'));
}
public function testSendRequestWithErrorAndReturnExceptionEnabled()
{
$client = new Client('', true, $this->httpClient);
$this->httpClient
->expects($this->once())
->method('execute')
->with($this->stringContains('{"jsonrpc":"2.0","method":"methodA","id":'))
->will($this->returnValue(array(
'jsonrpc' => '2.0',
'error' => array(
'code' => -32601,
'message' => 'Method not found',
),
)));
$result = $client->execute('methodA', array('a' => 'b'));
$this->assertInstanceOf('BadFunctionCallException', $result);
}
}

View File

@ -0,0 +1,220 @@
<?php
namespace JsonRPC;
require_once __DIR__.'/../../../vendor/autoload.php';
defined('CURLOPT_URL') or define('CURLOPT_URL', 10002);
defined('CURLOPT_RETURNTRANSFER') or define('CURLOPT_RETURNTRANSFER', 19913);
defined('CURLOPT_CONNECTTIMEOUT') or define('CURLOPT_CONNECTTIMEOUT', 78);
defined('CURLOPT_MAXREDIRS') or define('CURLOPT_MAXREDIRS', 68);
defined('CURLOPT_SSL_VERIFYPEER') or define('CURLOPT_SSL_VERIFYPEER', 64);
defined('CURLOPT_POST') or define('CURLOPT_POST', 47);
defined('CURLOPT_POSTFIELDS') or define('CURLOPT_POSTFIELDS', 10015);
defined('CURLOPT_HTTPHEADER') or define('CURLOPT_HTTPHEADER', 10023);
defined('CURLOPT_HEADERFUNCTION') or define('CURLOPT_HEADERFUNCTION', 20079);
defined('CURLOPT_CAINFO') or define('CURLOPT_CAINFO', 10065);
function extension_loaded($extension) {
return HttpClientTest::$functions->extension_loaded($extension);
}
function fopen($url, $mode, $use_include_path, $context)
{
return HttpClientTest::$functions->fopen($url, $mode, $use_include_path, $context);
}
function stream_context_create(array $params)
{
return HttpClientTest::$functions->stream_context_create($params);
}
function curl_init() {
return HttpClientTest::$functions->curl_init();
}
function curl_setopt_array($ch, array $params) {
HttpClientTest::$functions->curl_setopt_array($ch, $params);
}
function curl_setopt($ch, $option, $value) {
HttpClientTest::$functions->curl_setopt($ch, $option, $value);
}
function curl_exec($ch) {
return HttpClientTest::$functions->curl_exec($ch);
}
function curl_close($ch) {
HttpClientTest::$functions->curl_close($ch);
}
class HttpClientTest extends \PHPUnit_Framework_TestCase
{
public static $functions;
public function setUp()
{
self::$functions = $this
->getMockBuilder('stdClass')
->setMethods(array('extension_loaded', 'fopen', 'stream_context_create',
'curl_init', 'curl_setopt_array', 'curl_setopt', 'curl_exec', 'curl_close'))
->getMock();
}
public function testWithServerError()
{
$this->setExpectedException('\JsonRPC\Exception\ServerErrorException');
$httpClient = new HttpClient();
$httpClient->handleExceptions(array(
'HTTP/1.0 301 Moved Permanently',
'Connection: close',
'HTTP/1.1 500 Internal Server Error',
));
}
public function testWithConnectionFailure()
{
$this->setExpectedException('\JsonRPC\Exception\ConnectionFailureException');
$httpClient = new HttpClient();
$httpClient->handleExceptions(array(
'HTTP/1.1 404 Not Found',
));
}
public function testWithAccessForbidden()
{
$this->setExpectedException('\JsonRPC\Exception\AccessDeniedException');
$httpClient = new HttpClient();
$httpClient->handleExceptions(array(
'HTTP/1.1 403 Forbidden',
));
}
public function testWithAccessNotAllowed()
{
$this->setExpectedException('\JsonRPC\Exception\AccessDeniedException');
$httpClient = new HttpClient();
$httpClient->handleExceptions(array(
'HTTP/1.0 401 Unauthorized',
));
}
public function testWithCallback()
{
self::$functions
->expects($this->at(0))
->method('extension_loaded')
->with('curl')
->will($this->returnValue(false));
self::$functions
->expects($this->at(1))
->method('stream_context_create')
->with(array(
'http' => array(
'method' => 'POST',
'protocol_version' => 1.1,
'timeout' => 5,
'max_redirects' => 2,
'header' => implode("\r\n", array(
'User-Agent: JSON-RPC PHP Client <https://github.com/fguillot/JsonRPC>',
'Content-Type: application/json',
'Accept: application/json',
'Connection: close',
'Content-Length: 4',
)),
'content' => 'test',
'ignore_errors' => true,
),
'ssl' => array(
'verify_peer' => true,
'verify_peer_name' => true,
)
))
->will($this->returnValue('context'));
self::$functions
->expects($this->at(2))
->method('fopen')
->with('url', 'r', false, 'context')
->will($this->returnValue(false));
$httpClient = new HttpClient('url');
$httpClient->withBeforeRequestCallback(function(HttpClient $client, $payload) {
$client->withHeaders(array('Content-Length: '.strlen($payload)));
});
$this->setExpectedException('\JsonRPC\Exception\ConnectionFailureException');
$httpClient->execute('test');
}
public function testWithCurl()
{
self::$functions
->expects($this->at(0))
->method('extension_loaded')
->with('curl')
->will($this->returnValue(true));
self::$functions
->expects($this->at(1))
->method('curl_init')
->will($this->returnValue('curl'));
self::$functions
->expects($this->at(2))
->method('curl_setopt_array')
->with('curl', array(
CURLOPT_URL => 'url',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_MAXREDIRS => 2,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => 'test',
CURLOPT_HTTPHEADER => array(
'User-Agent: JSON-RPC PHP Client <https://github.com/fguillot/JsonRPC>',
'Content-Type: application/json',
'Accept: application/json',
'Connection: close',
'Content-Length: 4',
),
CURLOPT_HEADERFUNCTION => function ($curl, $header) use (&$headers) {
$headers[] = $header;
return strlen($header);
}
));
self::$functions
->expects($this->at(3))
->method('curl_setopt')
->with('curl', CURLOPT_CAINFO, 'test.crt');
self::$functions
->expects($this->at(4))
->method('curl_exec')
->with('curl')
->will($this->returnValue(false));
self::$functions
->expects($this->at(5))
->method('curl_close')
->with('curl');
$httpClient = new HttpClient('url');
$httpClient
->withSslLocalCert('test.crt')
->withBeforeRequestCallback(function(HttpClient $client, $payload) {
$client->withHeaders(array('Content-Length: '.strlen($payload)));
});
$this->setExpectedException('\JsonRPC\Exception\ConnectionFailureException');
$httpClient->execute('test');
}
}

View File

@ -0,0 +1,40 @@
<?php
use JsonRPC\Exception\AuthenticationFailureException;
use JsonRPC\MiddlewareHandler;
use JsonRPC\MiddlewareInterface;
require_once __DIR__.'/../../../vendor/autoload.php';
class FirstMiddleware implements MiddlewareInterface
{
public function execute($username, $password, $procedureName)
{
}
}
class SecondMiddleware implements MiddlewareInterface
{
public function execute($username, $password, $procedureName)
{
if ($username === 'myUsername' && $password === 'myPassword' && $procedureName === 'myProcedure') {
throw new AuthenticationFailureException('Bad user');
}
}
}
class MiddlewareHandlerTest extends PHPUnit_Framework_TestCase
{
public function testMiddlewareCanRaiseException()
{
$this->setExpectedException('JsonRpc\Exception\AuthenticationFailureException');
$middlewareHandler = new MiddlewareHandler();
$middlewareHandler->withUsername('myUsername');
$middlewareHandler->withPassword('myPassword');
$middlewareHandler->withProcedure('myProcedure');
$middlewareHandler->withMiddleware(new FirstMiddleware());
$middlewareHandler->withMiddleware(new SecondMiddleware());
$middlewareHandler->execute();
}
}

View File

@ -0,0 +1,153 @@
<?php
use JsonRPC\ProcedureHandler;
require_once __DIR__.'/../../../vendor/autoload.php';
class A
{
public function getAll($p1, $p2, $p3 = 4)
{
return $p1 + $p2 + $p3;
}
}
class B
{
public function getAll($p1)
{
return $p1 + 2;
}
}
class ClassWithBeforeMethod
{
private $foobar = '';
public function before($procedure)
{
$this->foobar = $procedure;
}
public function myProcedure()
{
return $this->foobar;
}
}
class ProcedureHandlerTest extends PHPUnit_Framework_TestCase
{
public function testProcedureNotFound()
{
$this->setExpectedException('BadFunctionCallException');
$handler = new ProcedureHandler;
$handler->executeProcedure('a');
}
public function testCallbackNotFound()
{
$this->setExpectedException('BadFunctionCallException');
$handler = new ProcedureHandler;
$handler->withCallback('b', function() {});
$handler->executeProcedure('a');
}
public function testClassNotFound()
{
$this->setExpectedException('BadFunctionCallException');
$handler = new ProcedureHandler;
$handler->withClassAndMethod('getAllTasks', 'c', 'getAll');
$handler->executeProcedure('getAllTasks');
}
public function testMethodNotFound()
{
$this->setExpectedException('BadFunctionCallException');
$handler = new ProcedureHandler;
$handler->withClassAndMethod('getAllTasks', 'A', 'getNothing');
$handler->executeProcedure('getAllTasks');
}
public function testIsPositionalArguments()
{
$handler = new ProcedureHandler;
$this->assertFalse($handler->isPositionalArguments(
array('a' => 'b', 'c' => 'd')
));
$handler = new ProcedureHandler;
$this->assertTrue($handler->isPositionalArguments(
array('a', 'b', 'c')
));
}
public function testBindNamedArguments()
{
$handler = new ProcedureHandler;
$handler->withClassAndMethod('getAllA', 'A', 'getAll');
$handler->withClassAndMethod('getAllB', 'B', 'getAll');
$handler->withClassAndMethod('getAllC', new B, 'getAll');
$this->assertEquals(6, $handler->executeProcedure('getAllA', array('p2' => 4, 'p1' => -2)));
$this->assertEquals(10, $handler->executeProcedure('getAllA', array('p2' => 4, 'p3' => 8, 'p1' => -2)));
$this->assertEquals(6, $handler->executeProcedure('getAllB', array('p1' => 4)));
$this->assertEquals(5, $handler->executeProcedure('getAllC', array('p1' => 3)));
}
public function testBindPositionalArguments()
{
$handler = new ProcedureHandler;
$handler->withClassAndMethod('getAllA', 'A', 'getAll');
$handler->withClassAndMethod('getAllB', 'B', 'getAll');
$this->assertEquals(6, $handler->executeProcedure('getAllA', array(4, -2)));
$this->assertEquals(2, $handler->executeProcedure('getAllA', array(4, 0, -2)));
$this->assertEquals(4, $handler->executeProcedure('getAllB', array(2)));
}
public function testRegisterNamedArguments()
{
$handler = new ProcedureHandler;
$handler->withCallback('getAllA', function($p1, $p2, $p3 = 4) {
return $p1 + $p2 + $p3;
});
$this->assertEquals(6, $handler->executeProcedure('getAllA', array('p2' => 4, 'p1' => -2)));
$this->assertEquals(10, $handler->executeProcedure('getAllA', array('p2' => 4, 'p3' => 8, 'p1' => -2)));
}
public function testRegisterPositionalArguments()
{
$handler = new ProcedureHandler;
$handler->withCallback('getAllA', function($p1, $p2, $p3 = 4) {
return $p1 + $p2 + $p3;
});
$this->assertEquals(6, $handler->executeProcedure('getAllA', array(4, -2)));
$this->assertEquals(2, $handler->executeProcedure('getAllA', array(4, 0, -2)));
}
public function testTooManyArguments()
{
$this->setExpectedException('InvalidArgumentException');
$handler = new ProcedureHandler;
$handler->withClassAndMethod('getAllC', new B, 'getAll');
$handler->executeProcedure('getAllC', array('p1' => 3, 'p2' => 5));
}
public function testNotEnoughArguments()
{
$this->setExpectedException('InvalidArgumentException');
$handler = new ProcedureHandler;
$handler->withClassAndMethod('getAllC', new B, 'getAll');
$handler->executeProcedure('getAllC');
}
public function testBeforeMethod()
{
$handler = new ProcedureHandler;
$handler->withObject(new ClassWithBeforeMethod);
$handler->withBeforeMethod('before');
$this->assertEquals('myProcedure', $handler->executeProcedure('myProcedure'));
}
}

View File

@ -0,0 +1,53 @@
<?php
use JsonRPC\Request\RequestBuilder;
require_once __DIR__.'/../../../../vendor/autoload.php';
class RequestBuilderTest extends PHPUnit_Framework_TestCase
{
public function testBuilder()
{
$payload = RequestBuilder::create()
->withId(123)
->withProcedure('foobar')
->withParams(array(1, 2, 3))
->build();
$this->assertEquals('{"jsonrpc":"2.0","method":"foobar","id":123,"params":[1,2,3]}', $payload);
}
public function testBuilderWithoutParams()
{
$payload = RequestBuilder::create()
->withId(123)
->withProcedure('foobar')
->build();
$this->assertEquals('{"jsonrpc":"2.0","method":"foobar","id":123}', $payload);
}
public function testBuilderWithoutId()
{
$payload = RequestBuilder::create()
->withProcedure('foobar')
->withParams(array(1, 2, 3))
->build();
$result = json_decode($payload, true);
$this->assertNotNull($result['id']);
}
public function testBuilderWithAdditionalRequestAttributes()
{
$payload = RequestBuilder::create()
->withProcedure('foobar')
->withParams(array(1, 2, 3))
->withRequestAttributes(array("some-attr" => 42))
->build();
$result = json_decode($payload, true);
$this->assertNotNull($result['some-attr']);
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace JsonRPC\Response;
use PHPUnit_Framework_TestCase;
require_once __DIR__.'/../../../../vendor/autoload.php';
function header($value)
{
HeaderMockTest::$functions->header($value);
}
abstract class HeaderMockTest extends PHPUnit_Framework_TestCase
{
public static $functions;
public function setUp()
{
self::$functions = $this
->getMockBuilder('stdClass')
->setMethods(array('header'))
->getMock();
}
}

View File

@ -0,0 +1,151 @@
<?php
use JsonRPC\Exception\AccessDeniedException;
use JsonRPC\Exception\AuthenticationFailureException;
use JsonRPC\Exception\InvalidJsonFormatException;
use JsonRPC\Exception\InvalidJsonRpcFormatException;
use JsonRPC\Exception\ResponseEncodingFailureException;
use JsonRPC\Exception\ResponseException;
use JsonRPC\Response\ResponseBuilder;
require_once __DIR__.'/../../../../vendor/autoload.php';
class ResponseBuilderTest extends PHPUnit_Framework_TestCase
{
public function testBuildResponse()
{
$response = ResponseBuilder::create()
->withId(123)
->withResult('test')
->build();
$this->assertEquals('{"jsonrpc":"2.0","result":"test","id":123}', $response);
}
public function testBuildResponseWithError()
{
$response = ResponseBuilder::create()
->withId(123)
->withResult('test')
->withError(42, 'Test', 'More info')
->build();
$this->assertEquals('{"jsonrpc":"2.0","error":{"code":42,"message":"Test","data":"More info"},"id":123}', $response);
}
public function testBuildResponseWithException()
{
$response = ResponseBuilder::create()
->withId(123)
->withResult('test')
->withException(new Exception('Test'))
->build();
$this->assertEquals('{"jsonrpc":"2.0","error":{"code":0,"message":"Test"},"id":123}', $response);
}
public function testBuildResponseWithResponseException()
{
$exception = new ResponseException('Error', 42);
$exception->setData('Data');
$response = ResponseBuilder::create()
->withId(123)
->withResult('test')
->withException($exception)
->build();
$this->assertEquals('{"jsonrpc":"2.0","error":{"code":42,"message":"Error","data":"Data"},"id":123}', $response);
}
public function testBuildResponseWithAccessDeniedException()
{
$responseBuilder = ResponseBuilder::create();
$response = $responseBuilder
->withId(123)
->withResult('test')
->withException(new AccessDeniedException('Test'))
->build();
$this->assertEquals('{"jsonrpc":"2.0","error":{"code":403,"message":"Forbidden"},"id":123}', $response);
$this->assertEquals('HTTP/1.0 403 Forbidden', $responseBuilder->getStatus());
$this->assertEquals(
array('Content-Type' => 'application/json'),
$responseBuilder->getHeaders()
);
}
public function testBuildResponseWithAuthenticationFailureException()
{
$responseBuilder = ResponseBuilder::create();
$response = $responseBuilder
->withId(123)
->withResult('test')
->withException(new AuthenticationFailureException('Test'))
->build();
$this->assertEquals('{"jsonrpc":"2.0","error":{"code":401,"message":"Unauthorized"},"id":123}', $response);
$this->assertEquals('HTTP/1.0 401 Unauthorized', $responseBuilder->getStatus());
$this->assertEquals(
array('Content-Type' => 'application/json', 'WWW-Authenticate' => 'Basic realm="JsonRPC"'),
$responseBuilder->getHeaders()
);
}
public function testBuildResponseWithResponseEncodingFailureException()
{
$response = ResponseBuilder::create()
->withId(123)
->withResult('test')
->withException(new ResponseEncodingFailureException('Test'))
->build();
$this->assertEquals('{"jsonrpc":"2.0","error":{"code":-32603,"message":"Internal error","data":"Test"},"id":123}', $response);
}
public function testBuildResponseWithInvalidArgumentException()
{
$response = ResponseBuilder::create()
->withId(123)
->withResult('test')
->withException(new InvalidArgumentException('Test'))
->build();
$this->assertEquals('{"jsonrpc":"2.0","error":{"code":-32602,"message":"Invalid params","data":"Test"},"id":123}', $response);
}
public function testBuildResponseWithBadFunctionCallException()
{
$response = ResponseBuilder::create()
->withId(123)
->withResult('test')
->withException(new BadFunctionCallException('Test'))
->build();
$this->assertEquals('{"jsonrpc":"2.0","error":{"code":-32601,"message":"Method not found"},"id":123}', $response);
}
public function testBuildResponseWithInvalidJsonRpcFormatException()
{
$response = ResponseBuilder::create()
->withId(123)
->withResult('test')
->withException(new InvalidJsonRpcFormatException('Test'))
->build();
$this->assertEquals('{"jsonrpc":"2.0","error":{"code":-32600,"message":"Invalid Request"},"id":null}', $response);
}
public function testBuildResponseWithInvalidJsonFormatException()
{
$response = ResponseBuilder::create()
->withId(123)
->withResult('test')
->withException(new InvalidJsonFormatException('Test'))
->build();
$this->assertEquals('{"jsonrpc":"2.0","error":{"code":-32700,"message":"Parse error"},"id":null}', $response);
}
}

View File

@ -0,0 +1,100 @@
<?php
use JsonRPC\Response\ResponseParser;
require_once __DIR__.'/../../../../vendor/autoload.php';
class ResponseParserTest extends PHPUnit_Framework_TestCase
{
public function testSingleRequest()
{
$result = ResponseParser::create()
->withPayload(json_decode('{"jsonrpc": "2.0", "result": "foobar", "id": "1"}', true))
->parse();
$this->assertEquals('foobar', $result);
}
public function testWithBadJsonFormat()
{
$this->setExpectedException('\JsonRPC\Exception\InvalidJsonFormatException');
ResponseParser::create()
->withPayload('foobar')
->parse();
}
public function testWithBadProcedure()
{
$this->setExpectedException('BadFunctionCallException');
ResponseParser::create()
->withPayload(json_decode('{"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found"}, "id": "1"}', true))
->parse();
}
public function testWithInvalidArgs()
{
$this->setExpectedException('InvalidArgumentException');
ResponseParser::create()
->withPayload(json_decode('{"jsonrpc": "2.0", "error": {"code": -32602, "message": "Invalid params"}, "id": "1"}', true))
->parse();
}
public function testWithInvalidRequest()
{
$this->setExpectedException('\JsonRPC\Exception\InvalidJsonRpcFormatException');
ResponseParser::create()
->withPayload(json_decode('{"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}', true))
->parse();
}
public function testWithParseError()
{
$this->setExpectedException('\JsonRPC\Exception\InvalidJsonFormatException');
ResponseParser::create()
->withPayload(json_decode('{"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error"}, "id": null}', true))
->parse();
}
public function testWithOtherError()
{
$this->setExpectedException('\JsonRPC\Exception\ResponseException');
ResponseParser::create()
->withPayload(json_decode('{"jsonrpc": "2.0", "error": {"code": 42, "message": "Something", "data": "foobar"}, "id": null}', true))
->parse();
}
public function testBatch()
{
$payload = '[
{"jsonrpc": "2.0", "result": 7, "id": "1"},
{"jsonrpc": "2.0", "result": 19, "id": "2"}
]';
$result = ResponseParser::create()
->withPayload(json_decode($payload, true))
->parse();
$this->assertEquals(array(7, 19), $result);
}
public function testBatchWithError()
{
$payload = '[
{"jsonrpc": "2.0", "result": 7, "id": "1"},
{"jsonrpc": "2.0", "result": 19, "id": "2"},
{"jsonrpc": "2.0", "error": {"code": -32602, "message": "Invalid params"}, "id": "1"}
]';
$this->setExpectedException('InvalidArgumentException');
ResponseParser::create()
->withPayload(json_decode($payload, true))
->parse();
}
}

View File

@ -0,0 +1,237 @@
<?php
use JsonRPC\Server;
require_once __DIR__.'/../../../vendor/autoload.php';
require_once __DIR__.'/Response/HeaderMockTest.php';
class C
{
public function doSomething()
{
return 'something';
}
}
class ServerProtocolTest extends \JsonRPC\Response\HeaderMockTest
{
public function testPositionalParameters()
{
$subtract = function ($minuend, $subtrahend) {
return $minuend - $subtrahend;
};
$server = new Server('{"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1}');
$server->register('subtract', $subtract);
$this->assertEquals(
json_decode('{"jsonrpc": "2.0", "result": 19, "id": 1}', true),
json_decode($server->execute(), true)
);
$server = new Server('{"jsonrpc": "2.0", "method": "subtract", "params": [23, 42], "id": 1}');
$server->register('subtract', $subtract);
$this->assertEquals(
json_decode('{"jsonrpc": "2.0", "result": -19, "id": 1}', true),
json_decode($server->execute(), true)
);
}
public function testNamedParameters()
{
$subtract = function ($minuend, $subtrahend) {
return $minuend - $subtrahend;
};
$server = new Server('{"jsonrpc": "2.0", "method": "subtract", "params": {"subtrahend": 23, "minuend": 42}, "id": 3}');
$server->register('subtract', $subtract);
$this->assertEquals(
json_decode('{"jsonrpc": "2.0", "result": 19, "id": 3}', true),
json_decode($server->execute(), true)
);
$server = new Server('{"jsonrpc": "2.0", "method": "subtract", "params": {"minuend": 42, "subtrahend": 23}, "id": 4}');
$server->register('subtract', $subtract);
$this->assertEquals(
json_decode('{"jsonrpc": "2.0", "result": 19, "id": 4}', true),
json_decode($server->execute(), true)
);
}
public function testNotification()
{
$update = function($p1, $p2, $p3, $p4, $p5) {};
$foobar = function() {};
$server = new Server('{"jsonrpc": "2.0", "method": "update", "params": [1,2,3,4,5]}');
$server->register('update', $update);
$server->register('foobar', $foobar);
$this->assertEquals('', $server->execute());
$server = new Server('{"jsonrpc": "2.0", "method": "foobar"}');
$server->register('update', $update);
$server->register('foobar', $foobar);
$this->assertEquals('', $server->execute());
}
public function testNoMethod()
{
$server = new Server('{"jsonrpc": "2.0", "method": "foobar", "id": "1"}');
$this->assertEquals(
json_decode('{"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found"}, "id": "1"}', true),
json_decode($server->execute(), true)
);
}
public function testInvalidJson()
{
$server = new Server('{"jsonrpc": "2.0", "method": "foobar, "params": "bar", "baz]');
$this->assertEquals(
json_decode('{"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error"}, "id": null}', true),
json_decode($server->execute(), true)
);
}
public function testInvalidRequest()
{
$server = new Server('{"jsonrpc": "2.0", "method": 1, "params": "bar", "id": 1}');
$this->assertEquals(
json_decode('{"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}', true),
json_decode($server->execute(), true)
);
}
public function testInvalidResponse_MalformedCharacters()
{
$server = new Server('{"jsonrpc": "2.0", "method": "invalidresponse","id": 1}');
$invalidresponse = function() {
return pack("H*" ,'c32e');
};
$server->register('invalidresponse', $invalidresponse);
$this->assertEquals(
json_decode('{"jsonrpc": "2.0","id": 1, "error": {"code": -32603, "message": "Internal error","data": "Malformed UTF-8 characters, possibly incorrectly encoded"}}', true),
json_decode($server->execute(), true)
);
}
public function testBatchInvalidJson()
{
$server = new Server('[
{"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"},
{"jsonrpc": "2.0", "method"
]');
$this->assertEquals(
json_decode('{"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error"}, "id": null}', true),
json_decode($server->execute(), true)
);
}
public function testBatchEmptyArray()
{
$server = new Server('[]');
$this->assertEquals(
json_decode('{"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null}', true),
json_decode($server->execute(), true)
);
}
public function testBatchNotEmptyButInvalid()
{
$server = new Server('[1]');
$this->assertEquals(
json_decode('[{"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error"}, "id": null}]', true),
json_decode($server->execute(), true)
);
}
public function testBatchInvalid()
{
$server = new Server('[1,2,3]');
$this->assertEquals(
json_decode('[
{"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error"}, "id": null},
{"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error"}, "id": null},
{"jsonrpc": "2.0", "error": {"code": -32700, "message": "Parse error"}, "id": null}
]', true),
json_decode($server->execute(), true)
);
}
public function testBatchOk()
{
$server = new Server('[
{"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"},
{"jsonrpc": "2.0", "method": "notify_hello", "params": [7]},
{"jsonrpc": "2.0", "method": "subtract", "params": [42,23], "id": "2"},
{"foo": "boo"},
{"jsonrpc": "2.0", "method": "foo.get", "params": {"name": "myself"}, "id": "5"},
{"jsonrpc": "2.0", "method": "get_data", "id": "9"},
{"jsonrpc": "2.0", "method": "doSomething", "id": 10},
{"jsonrpc": "2.0", "method": "doStuff", "id": 15}
]');
$server->register('sum', function($a, $b, $c) {
return $a + $b + $c;
});
$server->register('subtract', function($minuend, $subtrahend) {
return $minuend - $subtrahend;
});
$server->register('get_data', function() {
return array('hello', 5);
});
$server->attach(new C);
$server->bind('doStuff', 'C', 'doSomething');
$response = $server->execute();
$this->assertEquals(
json_decode('[
{"jsonrpc": "2.0", "result": 7, "id": "1"},
{"jsonrpc": "2.0", "result": 19, "id": "2"},
{"jsonrpc": "2.0", "error": {"code": -32600, "message": "Invalid Request"}, "id": null},
{"jsonrpc": "2.0", "error": {"code": -32601, "message": "Method not found"}, "id": "5"},
{"jsonrpc": "2.0", "result": ["hello", 5], "id": "9"},
{"jsonrpc": "2.0", "result": "something", "id": "10"},
{"jsonrpc": "2.0", "result": "something", "id": "15"}
]', true),
json_decode($response, true)
);
}
public function testBatchNotifications()
{
$server = new Server('[
{"jsonrpc": "2.0", "method": "notify_sum", "params": [1,2,4]},
{"jsonrpc": "2.0", "method": "notify_hello", "params": [7]}
]');
$server->register('notify_sum', function($a, $b, $c) {
});
$server->register('notify_hello', function($id) {
});
$this->assertEquals('', $server->execute());
}
}

View File

@ -0,0 +1,258 @@
<?php
use JsonRPC\Exception\AccessDeniedException;
use JsonRPC\Exception\AuthenticationFailureException;
use JsonRPC\Exception\ResponseException;
use JsonRPC\MiddlewareInterface;
use JsonRPC\Response\HeaderMockTest;
use JsonRPC\Server;
require_once __DIR__.'/../../../vendor/autoload.php';
require_once __DIR__.'/Response/HeaderMockTest.php';
class MyException extends Exception
{
}
class DummyMiddleware implements MiddlewareInterface
{
public function execute($username, $password, $procedureName)
{
throw new AuthenticationFailureException('Bad user');
}
}
class ServerTest extends HeaderMockTest
{
private $payload = '{"jsonrpc": "2.0", "method": "sum", "params": [1,2,4], "id": "1"}';
public function testCustomAuthenticationHeader()
{
$env = array(
'HTTP_X_AUTH' => base64_encode('myuser:mypassword'),
);
$server = new Server($this->payload, $env);
$server->setAuthenticationHeader('X-Auth');
$this->assertEquals('myuser', $server->getUsername());
$this->assertEquals('mypassword', $server->getPassword());
}
public function testCustomAuthenticationHeaderWithEmptyValue()
{
$server = new Server($this->payload);
$server->setAuthenticationHeader('X-Auth');
$this->assertNull($server->getUsername());
$this->assertNull($server->getPassword());
}
public function testGetUsername()
{
$server = new Server($this->payload);
$this->assertNull($server->getUsername());
$server = new Server($this->payload, array('PHP_AUTH_USER' => 'username'));
$this->assertEquals('username', $server->getUsername());
}
public function testGetPassword()
{
$server = new Server($this->payload);
$this->assertNull($server->getPassword());
$server = new Server($this->payload, array('PHP_AUTH_PW' => 'password'));
$this->assertEquals('password', $server->getPassword());
}
public function testExecute()
{
$server = new Server($this->payload);
$server->getProcedureHandler()->withCallback('sum', function($a, $b, $c) {
return $a + $b + $c;
});
self::$functions
->expects($this->once())
->method('header')
->with('Content-Type: application/json');
$this->assertEquals('{"jsonrpc":"2.0","result":7,"id":"1"}', $server->execute());
}
public function testExecuteRequestParserOverride()
{
$requestParser = $this->getMockBuilder('JsonRPC\Request\RequestParser')
->getMock();
$requestParser->method('withPayload')->willReturn($requestParser);
$requestParser->method('withProcedureHandler')->willReturn($requestParser);
$requestParser->method('withMiddlewareHandler')->willReturn($requestParser);
$requestParser->method('withLocalException')->willReturn($requestParser);
$server = new Server($this->payload, array(), null, $requestParser);
$requestParser->expects($this->once())
->method('parse');
$server->execute();
}
public function testExecuteBatchRequestParserOverride()
{
$batchRequestParser = $this->getMockBuilder('JsonRPC\Request\BatchRequestParser')
->getMock();
$batchRequestParser->method('withPayload')->willReturn($batchRequestParser);
$batchRequestParser->method('withProcedureHandler')->willReturn($batchRequestParser);
$batchRequestParser->method('withMiddlewareHandler')->willReturn($batchRequestParser);
$batchRequestParser->method('withLocalException')->willReturn($batchRequestParser);
$server = new Server('["...", "..."]', array(), null, null, $batchRequestParser);
$batchRequestParser->expects($this->once())
->method('parse');
$server->execute();
}
public function testExecuteResponseBuilderOverride()
{
$responseBuilder = $this->getMockBuilder('JsonRPC\Response\ResponseBuilder')
->getMock();
$responseBuilder->expects($this->once())
->method('sendHeaders');
$server = new Server($this->payload, array(), $responseBuilder);
$server->execute();
}
public function testExecuteProcedureHandlerOverride()
{
$batchRequestParser = $this->getMockBuilder('JsonRPC\Request\BatchRequestParser')
->getMock();
$procedureHandler = $this->getMockBuilder('JsonRPC\ProcedureHandler')
->getMock();
$batchRequestParser->method('withPayload')->willReturn($batchRequestParser);
$batchRequestParser->method('withProcedureHandler')->willReturn($batchRequestParser);
$batchRequestParser->method('withMiddlewareHandler')->willReturn($batchRequestParser);
$batchRequestParser->method('withLocalException')->willReturn($batchRequestParser);
$server = new Server('["...", "..."]', array(), null, null, $batchRequestParser, $procedureHandler);
$batchRequestParser->expects($this->once())
->method('parse');
$batchRequestParser->expects($this->once())
->method('withProcedureHandler')
->with($this->identicalTo($procedureHandler));
$server->execute();
}
public function testWhenCallbackRaiseForbiddenException()
{
$server = new Server($this->payload);
$server->getProcedureHandler()->withCallback('sum', function($a, $b, $c) {
throw new AccessDeniedException();
});
self::$functions
->expects($this->at(0))
->method('header')
->with('HTTP/1.0 403 Forbidden');
self::$functions
->expects($this->at(1))
->method('header')
->with('Content-Type: application/json');
$this->assertEquals('{"jsonrpc":"2.0","error":{"code":403,"message":"Forbidden"},"id":null}', $server->execute());
}
public function testWhenCallbackRaiseUnauthorizedException()
{
$server = new Server($this->payload);
$server->getProcedureHandler()->withCallback('sum', function($a, $b, $c) {
throw new AuthenticationFailureException();
});
self::$functions
->expects($this->at(0))
->method('header')
->with('HTTP/1.0 401 Unauthorized');
self::$functions
->expects($this->at(1))
->method('header')
->with('Content-Type: application/json');
$this->assertEquals('{"jsonrpc":"2.0","error":{"code":401,"message":"Unauthorized"},"id":null}', $server->execute());
}
public function testWhenMiddlewareRaiseUnauthorizedException()
{
$server = new Server($this->payload);
$server->getMiddlewareHandler()->withMiddleware(new DummyMiddleware());
$server->getProcedureHandler()->withCallback('sum', function($a, $b) {
return $a + $b;
});
self::$functions
->expects($this->at(0))
->method('header')
->with('HTTP/1.0 401 Unauthorized');
self::$functions
->expects($this->at(1))
->method('header')
->with('Content-Type: application/json');
$this->assertEquals('{"jsonrpc":"2.0","error":{"code":401,"message":"Unauthorized"},"id":null}', $server->execute());
}
public function testFilterRelayExceptions()
{
$server = new Server($this->payload);
$server->withLocalException('MyException');
$server->getProcedureHandler()->withCallback('sum', function($a, $b, $c) {
throw new MyException('test');
});
$this->setExpectedException('MyException');
$server->execute();
}
public function testCustomExceptionAreRelayedToClient()
{
$server = new Server($this->payload);
$server->getProcedureHandler()->withCallback('sum', function($a, $b, $c) {
throw new MyException('test');
});
self::$functions
->expects($this->once())
->method('header')
->with('Content-Type: application/json');
$this->assertEquals('{"jsonrpc":"2.0","error":{"code":0,"message":"test"},"id":"1"}', $server->execute());
}
public function testCustomResponseException()
{
$server = new Server($this->payload);
$server->getProcedureHandler()->withCallback('sum', function($a, $b, $c) {
throw new ResponseException('test', 123, null, 'more info');
});
self::$functions
->expects($this->once())
->method('header')
->with('Content-Type: application/json');
$this->assertEquals('{"jsonrpc":"2.0","error":{"code":123,"message":"test","data":"more info"},"id":"1"}', $server->execute());
}
}

View File

@ -0,0 +1,32 @@
<?php
use JsonRPC\Validator\HostValidator;
require_once __DIR__.'/../../../../vendor/autoload.php';
class HostValidatorTest extends PHPUnit_Framework_TestCase
{
public function testWithEmptyHosts()
{
$this->assertNull(HostValidator::validate(array(), '127.0.0.1', '127.0.0.1'));
}
public function testWithValidHosts()
{
$this->assertNull(HostValidator::validate(array('127.0.0.1'), '127.0.0.1', '127.0.0.1'));
}
public function testWithValidNetwork()
{
$this->assertNull(HostValidator::validate(array('192.168.10.1/24'), '192.168.10.1'),'test ip match');
$this->assertNull(HostValidator::validate(array('192.168.10.1/24'), '192.168.10.250'),'test ip match');
$this->setExpectedException('\JsonRPC\Exception\AccessDeniedException');
HostValidator::validate(array('192.168.10.1/24'), '192.168.11.1');
}
public function testWithNotAuthorizedHosts()
{
$this->setExpectedException('\JsonRPC\Exception\AccessDeniedException');
HostValidator::validate(array('192.168.1.1'), '127.0.0.1', '127.0.0.1');
}
}

View File

@ -0,0 +1,22 @@
<?php
use JsonRPC\Validator\JsonEncodingValidator;
require_once __DIR__.'/../../../../vendor/autoload.php';
class JsonEncodingValidatorTest extends PHPUnit_Framework_TestCase
{
public function testWithValidJson()
{
json_encode('{"foo": "bar"}');
$this->assertNull(JsonEncodingValidator::validate());
}
public function testWithJsonError()
{
json_encode("\xB1\x31");
$this->setExpectedException('\JsonRPC\Exception\ResponseEncodingFailureException');
JsonEncodingValidator::validate();
}
}

View File

@ -0,0 +1,19 @@
<?php
use JsonRPC\Validator\JsonFormatValidator;
require_once __DIR__.'/../../../../vendor/autoload.php';
class JsonFormatValidatorTest extends PHPUnit_Framework_TestCase
{
public function testJsonParsedCorrectly()
{
$this->assertNull(JsonFormatValidator::validate(array('foobar')));
}
public function testJsonNotParsedCorrectly()
{
$this->setExpectedException('\JsonRPC\Exception\InvalidJsonFormatException');
JsonFormatValidator::validate('');
}
}

View File

@ -0,0 +1,48 @@
<?php
use JsonRPC\Validator\RpcFormatValidator;
require_once __DIR__.'/../../../../vendor/autoload.php';
class RpcFormatValidatorTest extends PHPUnit_Framework_TestCase
{
public function testWithMinimumRequirement()
{
$this->assertNull(RpcFormatValidator::validate(array('jsonrpc' => '2.0', 'method' => 'foobar')));
}
public function testWithNoVersion()
{
$this->setExpectedException('\JsonRPC\Exception\InvalidJsonRpcFormatException');
RpcFormatValidator::validate(array('method' => 'foobar'));
}
public function testWithNoMethod()
{
$this->setExpectedException('\JsonRPC\Exception\InvalidJsonRpcFormatException');
RpcFormatValidator::validate(array('jsonrpc' => '2.0'));
}
public function testWithMethodNotString()
{
$this->setExpectedException('\JsonRPC\Exception\InvalidJsonRpcFormatException');
RpcFormatValidator::validate(array('jsonrpc' => '2.0', 'method' => array()));
}
public function testWithBadVersion()
{
$this->setExpectedException('\JsonRPC\Exception\InvalidJsonRpcFormatException');
RpcFormatValidator::validate(array('jsonrpc' => '1.0', 'method' => 'abc'));
}
public function testWithBadParams()
{
$this->setExpectedException('\JsonRPC\Exception\InvalidJsonRpcFormatException');
RpcFormatValidator::validate(array('jsonrpc' => '2.0', 'method' => 'abc', 'params' => 'foobar'));
}
public function testWithParams()
{
$this->assertNull(RpcFormatValidator::validate(array('jsonrpc' => '2.0', 'method' => 'abc', 'params' => array(1, 2))));
}
}

View File

@ -0,0 +1,24 @@
<?php
use JsonRPC\Validator\UserValidator;
require_once __DIR__.'/../../../../vendor/autoload.php';
class UserValidatorTest extends PHPUnit_Framework_TestCase
{
public function testWithEmptyHosts()
{
$this->assertNull(UserValidator::validate(array(), 'user', 'pass'));
}
public function testWithValidHosts()
{
$this->assertNull(UserValidator::validate(array('user' => 'pass'), 'user', 'pass'));
}
public function testWithNotAuthorizedHosts()
{
$this->setExpectedException('\JsonRPC\Exception\AuthenticationFailureException');
UserValidator::validate(array('user' => 'pass'), 'user', 'wrong password');
}
}

View File

Before

Width:  |  Height:  |  Size: 126 B

After

Width:  |  Height:  |  Size: 126 B

View File

Before

Width:  |  Height:  |  Size: 202 B

After

Width:  |  Height:  |  Size: 202 B

View File

Before

Width:  |  Height:  |  Size: 205 B

After

Width:  |  Height:  |  Size: 205 B

View File

Before

Width:  |  Height:  |  Size: 216 B

After

Width:  |  Height:  |  Size: 216 B

View File

Before

Width:  |  Height:  |  Size: 210 B

After

Width:  |  Height:  |  Size: 210 B

View File

Before

Width:  |  Height:  |  Size: 213 B

After

Width:  |  Height:  |  Size: 213 B

View File

Before

Width:  |  Height:  |  Size: 219 B

After

Width:  |  Height:  |  Size: 219 B

View File

Before

Width:  |  Height:  |  Size: 211 B

After

Width:  |  Height:  |  Size: 211 B

View File

Before

Width:  |  Height:  |  Size: 211 B

After

Width:  |  Height:  |  Size: 211 B

View File

Before

Width:  |  Height:  |  Size: 228 B

After

Width:  |  Height:  |  Size: 228 B

View File

Before

Width:  |  Height:  |  Size: 225 B

After

Width:  |  Height:  |  Size: 225 B

View File

Before

Width:  |  Height:  |  Size: 144 B

After

Width:  |  Height:  |  Size: 144 B

View File

Before

Width:  |  Height:  |  Size: 225 B

After

Width:  |  Height:  |  Size: 225 B

View File

Before

Width:  |  Height:  |  Size: 235 B

After

Width:  |  Height:  |  Size: 235 B

View File

Before

Width:  |  Height:  |  Size: 226 B

After

Width:  |  Height:  |  Size: 226 B

View File

Before

Width:  |  Height:  |  Size: 220 B

After

Width:  |  Height:  |  Size: 220 B

View File

Before

Width:  |  Height:  |  Size: 242 B

After

Width:  |  Height:  |  Size: 242 B

View File

Before

Width:  |  Height:  |  Size: 242 B

After

Width:  |  Height:  |  Size: 242 B

View File

Before

Width:  |  Height:  |  Size: 244 B

After

Width:  |  Height:  |  Size: 244 B

View File

Before

Width:  |  Height:  |  Size: 237 B

After

Width:  |  Height:  |  Size: 237 B

View File

Before

Width:  |  Height:  |  Size: 234 B

After

Width:  |  Height:  |  Size: 234 B

View File

Before

Width:  |  Height:  |  Size: 232 B

After

Width:  |  Height:  |  Size: 232 B

View File

Before

Width:  |  Height:  |  Size: 147 B

After

Width:  |  Height:  |  Size: 147 B

View File

Before

Width:  |  Height:  |  Size: 255 B

After

Width:  |  Height:  |  Size: 255 B

View File

Before

Width:  |  Height:  |  Size: 260 B

After

Width:  |  Height:  |  Size: 260 B

View File

Before

Width:  |  Height:  |  Size: 262 B

After

Width:  |  Height:  |  Size: 262 B

View File

Before

Width:  |  Height:  |  Size: 253 B

After

Width:  |  Height:  |  Size: 253 B

Some files were not shown because too many files have changed in this diff Show More