diff --git a/libs/jsonrpc/src/JsonRPC/Request/BatchRequestParser.php b/libs/jsonrpc/src/JsonRPC/Request/BatchRequestParser.php index c0fc776..d9eaf5a 100644 --- a/libs/jsonrpc/src/JsonRPC/Request/BatchRequestParser.php +++ b/libs/jsonrpc/src/JsonRPC/Request/BatchRequestParser.php @@ -2,6 +2,9 @@ namespace JsonRPC\Request; +use JsonRPC\Exception\AccessDeniedException; +use JsonRPC\Response\ResponseBuilder; + /** * Class BatchRequestParser * @@ -21,12 +24,21 @@ class BatchRequestParser extends RequestParser $responses = array(); foreach ($this->payload as $payload) { - $responses[] = RequestParser::create() - ->withPayload($payload) - ->withProcedureHandler($this->procedureHandler) - ->withMiddlewareHandler($this->middlewareHandler) - ->withLocalException($this->localExceptions) - ->parse(); + try { + $responses[] = RequestParser::create() + ->withPayload($payload) + ->withProcedureHandler($this->procedureHandler) + ->withMiddlewareHandler($this->middlewareHandler) + ->withLocalException($this->localExceptions) + ->parse(); + } catch (AccessDeniedException $e) { + //Bad credentials still fail the whole call, but a forbidden + //resource concerns only the request that asked for it + $responses[] = ResponseBuilder::create() + ->withId(isset($payload['id']) ? $payload['id'] : null) + ->withException($e) + ->build(); + } } $responses = array_filter($responses); diff --git a/tests/units/Api/BatchRequestTest.php b/tests/units/Api/BatchRequestTest.php new file mode 100644 index 0000000..923ee52 --- /dev/null +++ b/tests/units/Api/BatchRequestTest.php @@ -0,0 +1,58 @@ +register('getVersion', function () { + return '1.2.3'; + }); + + $server->register('getProjectById', function () { + throw new AccessDeniedException('Forbidden'); + }); + + $this->assertEquals( + json_decode('[ + {"jsonrpc": "2.0", "result": "1.2.3", "id": 1}, + {"jsonrpc": "2.0", "error": {"code": 403, "message": "Forbidden"}, "id": 2}, + {"jsonrpc": "2.0", "result": "1.2.3", "id": 3} + ]', true), + json_decode($server->execute(), true) + ); + } + + public function testWrongCredentialsStillFailTheWholeBatch() + { + $server = new Server('[ + {"jsonrpc": "2.0", "method": "getVersion", "id": 1}, + {"jsonrpc": "2.0", "method": "getProjectById", "id": 2} + ]'); + + $server->register('getVersion', function () { + return '1.2.3'; + }); + + $server->register('getProjectById', function () { + throw new AuthenticationFailureException('Wrong credentials'); + }); + + $this->assertEquals( + json_decode('{"jsonrpc": "2.0", "error": {"code": 401, "message": "Unauthorized"}, "id": null}', true), + json_decode($server->execute(), true) + ); + } +}